---
title: 'Zamanlanmış Tetikleme'
source: 'https://academia.sh/tr/kurslar/sunucusuz/zamanlanmis-tetikleme'
course: 'Sunucusuz ve Kenar Bilişim'
language: tr
updated: '2026-08-17T18:06:57+00:00'
license: 'CC BY-SA 4.0'
---

# Zamanlanmış Tetikleme

Saatin bir hizmete devredilmesinin getirdiği garanti türü: otuz gecelik toplu faturalama koşumunda aynı dakikada gelen iki tetiklemenin ürettiği yinelenen fatura sayısının ölçülmesi, etkisizlik anahtarının bunu kapatırken kaçırılan koşumu kapatmaması ve iş penceresinin tetikleme anından türetilmesiyle veriden türetilmesi arasındaki farkın saat kayması altında sayılması.

Önceki dersteki akışın tamamı bir olayla başlıyordu: okuma geldi, doğrulama tetiklendi, zincir
yürüdü. Ölçüm ağının işlerinin bir bölümünde ise böyle bir olay yoktur. Gece toplu faturalama,
günlük mutabakat ve haftalık sayaç sağlık taraması hiçbir okumanın gelişine bağlı değildir;
onları başlatan tek şey saattir.

Zamanlanmış işin kendisi yeni değildir; kaçırılan koşum ve üst üste binme politikaları daha önce
ölçüldü ve o karşılaştırma burada tekrarlanmaz. Bu dersin sorusu dardır: saati **bir hizmet**
tuttuğunda ne değişir?

## Devredilen Karar ve Garantinin Türü

Kendi işlettiği bir zamanlayıcıda saat, belirli bir makinede çalışan belirli bir süreçtir. O
makine ölürse tetikleme olmaz; iki makine birden çalışırsa tetikleme iki kez olur. İkisi de
görülebilir, ikisi de düzeltilebilir — çünkü saati tutan şey elin altındadır.

Hizmet olarak alınan bir zamanlayıcıda bu sorumluluk devredilir. Karşılığında gelen kısıt bir
cümleyle yazılır ve bu dersin ekseni odur: **garanti en az bir kezdir.** Hizmet tetiklemenin
gerçekleşeceğini üstlenir, bir kez gerçekleşeceğini üstlenmez. Aynı dakikada iki tetikleme
olabilir; bu bir arıza değil, ilan edilmiş davranıştır. İşin etkisiz olması bu yüzden iyi bir
uygulama değil, hizmetin ön koşuludur.

Devredilenler sayılabilir: saati tutan sürecin ayakta kalması, o sürecin tek örnekli olması,
makine değiştiğinde zamanlamanın kaybolmaması, tetikleme kaydının tutulması. Geriye kalan yüzey
yine küçüktür — zamanlama ifadesi, saat dilimi, hedef, hedefe geçilecek girdi ve tetikleme
başarısız olursa uygulanacak yeniden deneme politikası: beş kalem. Önceki derslerdeki kuyruk
yapılandırmasıyla aynı büyüklükte bir yüzey, aynı türden bir kısıt.

Saat dilimi kalemi tek başına bir örnektir. Zamanlama yerel saate göre yazıldığında yılda iki
gece 24 saat sürmez; biri 23, öteki 25 saattir. Günde bir kez koşan bir iş o gecelerin birinde
iki kez, ötekinde hiç koşmayabilir. Yani ölçümdeki iki kusur — çift koşum ve kaçırılan koşum —
saat diliminin kendisinden de doğar ve bunun tetiklemenin doğruluğuyla ilgisi yoktur.

İkinci kısıt tersidir. Tetikleme anında hedef ayakta değilse — işlev kısılmışsa, hesap
sınırındaysa, dağıtım yarıdaysa — o koşum **kaçırılır ve telafi edilmez**. Zamanlayıcı yalnız
"şimdi"yi bilir; geçmiş bir anı yeniden üretmez. İki kısıt birlikte tuhaf bir çift oluşturur:
aynı iş bazen iki kez koşar, bazen hiç koşmaz.

Ölçüm kurgu bölgesel ölçüm ağının gece toplu faturalama işi üzerindedir.

- **OS19.** Otuz gecelik koşum; her gece 1.200 abone faturalanır, beklenen toplam 36.000 fatura.
- **OS20.** On birde bir gecede tetikleme aynı dakikada iki kez gelir, on üçte bir gecede hiç
  gelmez; günler sabittir, modelde rastgelelik yoktur.
- **OS21.** Etkisizlik anahtarı dönem ile abone kimliğinden türetilir; anahtar varsa ikinci
  yazma atlanır.
- **OS22.** Tetikleme anı hedeflenen andan −60 ile +60 birim arasında kayar; kayma güne göre
  belirlidir.
- **OS23.** Gün 1.440 birimdir ve okumalar gün içine eşit dağılır.
- **OS24.** Model üst üste binen koşumların iç kilitlenmesini kurmaz; yalnız yazılan fatura ve
  işlenen okuma sayılır.

## Aynı Dakikada İki Tetikleme

```js
// tetikleme.mjs — zamanlanmis tetikleme modeli: en az bir kez garantisi ve kacirilan kosum
// Model: gercek bir zamanlayici degil, garanti turunun fatura sayisina etkisinin sayilmasi.
const GUN = 30, ABONE = 1200;
const CIFT = (g) => g % 11 === 4;      // bu gecelerde tetikleme ayni dakikada iki kez geldi
const KACAN = (g) => g % 13 === 9;     // bu gecelerde tetikleme hic gelmedi

function kosum(anahtarVar) {
  const yazilan = new Set();
  let fatura = 0, yinelenen = 0, eksik = 0, tetikleme = 0;
  for (let g = 0; g < GUN; g++) {
    if (KACAN(g)) { eksik += ABONE; continue; }        // telafi yok: gun bir daha gelmez
    for (let t = 0; t < (CIFT(g) ? 2 : 1); t++) {
      tetikleme++;
      for (let a = 0; a < ABONE; a++) {
        const anahtar = `d${g}:a${a}`;                 // etkisizlik anahtari: donem + abone
        if (anahtarVar && yazilan.has(anahtar)) continue;
        yazilan.add(anahtar); fatura++;
        if (t > 0) yinelenen++;
      }
    }
  }
  return { tetikleme, fatura, yinelenen, eksik };
}

console.log("etkisizlik anahtari".padEnd(21) + "tetikleme".padStart(11) +
  "yazilan fatura".padStart(16) + "yinelenen".padStart(11) + "eksik".padStart(8));
for (const [ad, v] of [["yok", false], ["var", true]]) {
  const s = kosum(v);
  console.log(ad.padEnd(21) + String(s.tetikleme).padStart(11) + String(s.fatura).padStart(16) +
    String(s.yinelenen).padStart(11) + String(s.eksik).padStart(8));
}
console.log(`gun: ${GUN}, abone: ${ABONE}, beklenen fatura: ${GUN * ABONE}`);
```

```sh
node tetikleme.mjs
```

```
etkisizlik anahtari    tetikleme  yazilan fatura  yinelenen   eksik
yok                           31           37200       3600    2400
var                           31           33600          0    2400
gun: 30, abone: 1200, beklenen fatura: 36000
```

Tablo aynı otuz geceyi iki kez işler; tek fark, yazma sırasında etkisizlik anahtarının
sorulup sorulmamasıdır. Otuz gece için 31 tetikleme geldi. Sayı otuz değil, çünkü iki gece hiç tetikleme olmadı ve üç
gecede ikişer tetikleme geldi: 28 + 3. Tek başına bu sayı zararsız görünüyor; faturaya
yansıması ilk satırdadır.

Etkisizlik anahtarı olmadan **3.600 yinelenen fatura** yazıldı. Üç gecenin her birinde 1.200
abone iki kez faturalandı. Ölçüm ağında bunun anlamı şudur: üç bin altı yüz aboneye aynı dönem
için ikinci bir fatura çıktı, ikinci bir borç kaydı oluştu ve — önceki derslerdeki zincir
düşünülürse — muhtemelen ikinci bir bildirim gitti. Hiçbir yerde hata yoktur; iki koşum da
başarıyla bitmiştir.

Yinelenen faturanın yanında ikinci bir sayı daha var: 3.600 fazladan işlev çağrısı. Abone başına
bir çağrı sayıldığında üç gece boyunca yapılan iş iki katına çıkar, eşzamanlılık havuzundan iki
kat yer tutulur ve faturalama penceresi uzar. Üstelik iki koşum aynı dakikada başladığı için
üst üste binerler; aynı abonenin kaydına iki koşum aynı anda yazar. Yazmanın kendisi bir tekillik
kısıtına dayanmıyorsa, tabloda iki satır birden oluşur ve ikisi de "başarılı" sayılır. Çift
tetiklemenin bedeli bu yüzden yalnız yinelenen kayıt değil, aynı zamanda kayıt düzeyinde bir
yarıştır.

İkinci satır anahtarın ne yaptığını gösteriyor. Tetikleme sayısı **yine 31'dir** — anahtar
tetiklemeyi tekilleştirmez, hizmet ikinci tetiklemeyi göndermeye devam eder. Değişen şey
yazmadır: dönem ile abone kimliğinden türetilen anahtar zaten yazılmışsa ikinci yazma atlanır
ve yinelenen fatura sıfıra iner. Bu, teslim semantiği ölçümünde kurulan ayrımın aynısıdır —
tekilleştirilen şey teslim değil, etkidir.

Anahtarın neyden türetildiği burada belirleyicidir. Ölçümde anahtar dönem ile abone
kimliğinden yapıldı; ikinci tetikleme aynı dönemi getirdiği için aynı anahtarı üretti ve yazma
atlandı. Anahtar koşum kimliğinden türetilseydi — her tetikleme kendi kimliğiyle geldiği için —
iki koşum iki ayrı anahtar üretir ve tablodaki ilk satıra geri dönülürdü. Anahtar, tekrarın
hangi ölçüte göre "aynı iş" sayılacağını tanımlar; zamanlanmış işte bu ölçüt her zaman **işin
kapsamıdır**, koşumun kendisi değil. Ölçüm ağında kapsam "hangi dönem, hangi abone"dir; aynı
dönem iki kez faturalanamaz, çünkü ikinci fatura yeni bir olgu değil, birincinin kopyasıdır.

## Anahtarın Kapatmadığı Sütun

Tablonun son sütunu iki satırda da aynıdır: **2.400 eksik fatura.** Etkisizlik anahtarı bu
sayıya dokunmaz, çünkü anahtar yalnız "bu iş daha önce yapıldı mı" sorusunu yanıtlar; hiç
yapılmamış bir iş için sorulacak bir soru yoktur.

Eksik sütununun asıl güçlüğü fark edilme süresidir. Yinelenen fatura kendini gösterir: abone
ikinci bildirimi alır, borç iki kez düşer, çağrı merkezine bir soru gelir. Eksik fatura hiçbir
belirti üretmez — üretilmeyen fatura kimseyi rahatsız etmez. 2.400 fatura, otuz günlük dönemin
yüzde 6,7'sidir ve bu fark ancak dönem sonu mutabakatında, gelir beklentisiyle karşılaştırma
yapıldığında görünür. Ölçümdeki iki eksik gecenin maliyeti bu yüzden yalnız 2.400 fatura değil,
o faturaların bir ay geç kesilmesidir.

Kaçırılan koşum, hizmetin garantisinin öteki yüzüdür ve düzeltilmesi tetikleme tarafında değil
**iş tanımı** tarafındadır. Aradaki fark tek cümlede durur: iş "bugünü faturala" diye
yazılırsa kaçan gün bir daha gelmez; "faturalanmamış dönemleri faturala" diye yazılırsa ertesi
gece iki günü birden kapatır. İkinci biçim aynı zamanda çift tetiklemeye de dayanıklıdır,
çünkü ikinci koşum faturalanmamış dönem bulamaz.

Bu biçimin bedeli iki kalemdir. Birincisi, işin artık kendi kapsamını bulması gerekir: her
koşumda "hangi dönemler işlenmedi" sorgusu çalışır ve bu sorgu, koşum ne kadar seyrek kaçarsa
o kadar sık boşuna koşar. İkincisi, kaçan gün sayısı arttıkça tek bir koşumun iş yükü
katlanır — iki gün üst üste kaçarsa üçüncü gece 3.600 fatura yazılır ve bu, işlev süre
sınırının içinde bitmek zorundadır. Kapsam tabanlı iş, kaçırma sorununu bir süre sınırı
sorununa çevirir.

Üçüncü bir seçenek, koşumun gerçekleştiğini ayrı bir yerde işaretleyip eksik günleri arayan bir
denetçi kurmaktır. Bu, kaçırmayı **görünür** kılar ama kendisi de zamanlanmış bir iştir ve aynı
garantiye tabidir; denetçinin kaçırdığı koşumu bulacak bir üçüncü katman yoktur.

Üç seçenek arasındaki tercih, işin doğasına bakılarak yapılır. Faturalama gibi kapsamı veriden
okunabilen işlerde ikinci biçim doğrudan uygulanır. Kapsamı olmayan işlerde — örneğin bir
önbelleği ısıtan ya da geçici dosyaları silen bir koşumda — kaçan bir gecenin telafi edilecek
bir karşılığı da yoktur; orada kaçırma bir kusur değil, kabul edilmiş bir durumdur. Ayrımı
yapmanın ölçütü tek sorudur: koşum kaçtığında geriye eksik bir **kayıt** kalıyor mu? Kalıyorsa
kapsam tabanlı yazım zorunludur; kalmıyorsa zamanlayıcının garantisi olduğu gibi kabul edilir.

## Saat Kayması ve Pencerenin Kaynağı

Tetiklemenin bir de anı vardır. Hizmet "her gece belirli bir dakikada" der, ama gerçekleşen an
o dakikanın etrafında kayar: sıra beklemesi, ölçekleme gecikmesi, saat eşitleme farkı. Kayma
küçüktür; sorun kaymanın büyüklüğü değil, **işin penceresini nereden aldığıdır.** Aşağıdaki
koşum aynı otuz geceyi iki pencere tanımıyla işler: biri pencereyi tetikleme anından geriye
sayar, öteki bir önceki koşumun bıraktığı yerden başlatır. Kayma ikisinde de aynıdır.

```js
// kayma.mjs — saat kaymasi: is penceresi tetikleme aninin mi, verinin mi uzerine kuruluyor
const GUN = 30, GUNLUK = 1200, DAKIKA = 1440;
const kayma = (g) => ((g * 37) % 121) - 60;      // -60..+60 birim, gune gore belirli
const tetik = (g) => (g + 1) * DAKIKA + kayma(g);

const OKUMA = [];                                 // okumalar gun icine esit dagilir
for (let g = 0; g < GUN; g++)
  for (let i = 0; i < GUNLUK; i++) OKUMA.push(g * DAKIKA + Math.floor((i * DAKIKA) / GUNLUK));

function kosum(kapsamli) {
  const sayac = new Map(OKUMA.map((z, i) => [i, 0]));
  let son = 0;
  for (let g = 0; g < GUN; g++) {
    const T = tetik(g);
    const bas = kapsamli ? son : T - DAKIKA;      // kapsamli: son islenen andan itibaren
    OKUMA.forEach((z, i) => { if (z >= bas && z < T) sayac.set(i, sayac.get(i) + 1); });
    son = T;
  }
  let hic = 0, cift = 0;
  for (const n of sayac.values()) { if (n === 0) hic++; else if (n > 1) cift += n - 1; }
  return { hic, cift };
}

console.log("pencere".padEnd(22) + "hic islenmeyen".padStart(16) + "cift islenen".padStart(14));
for (const [ad, k] of [["tetikleme anindan", false], ["son islenen andan", true]]) {
  const s = kosum(k);
  console.log(ad.padEnd(22) + String(s.hic).padStart(16) + String(s.cift).padStart(14));
}
console.log(`okuma: ${OKUMA.length}, kayma araligi: -60..+60 birim`);
```

```sh
node kayma.mjs
```

```
pencere                 hic islenmeyen  cift islenen
tetikleme anindan                  648           560
son islenen andan                    0             0
okuma: 36000, kayma araligi: -60..+60 birim
```

Pencere tetikleme anından geriye sayıldığında 36.000 okumanın **648'i hiç işlenmedi**, 560'ı
**iki kez işlendi**. Ne bir hata oluştu ne de tetikleme kaçtı; her gece iş koştu ve başarıyla
bitti. Kayan tek şey pencerenin iki ucuydu. Bir gece erken, ertesi gece geç tetiklendiğinde
aradaki dilim iki pencerede birden kalır; tersi durumda hiçbir pencereye girmez.

648 okuma, 36.000'in yüzde 1,8'idir ve bu oran yanıltıcıdır — kayıp rastgele dağılmaz. Kaçan
dilim her zaman gün sınırının etrafındadır, yani hep aynı saatlerde okuma gönderen sayaçlara
denk gelir. Sabit saatte rapor eden bir sayaç filosunda bu, her ay aynı abone kümesinin eksik
faturalanması demektir; yüzde 1,8'lik bir genel kayıp değil, bir avuç abonede yüzde yüze yakın
bir kayıptır. Çift işlenen 560 okuma da aynı kümededir ve iki hata birbirini gizler: toplam
tüketim rakamına bakan bir denetim, 648 eksikle 560 fazlanın birbirini kısmen götürdüğünü görüp
sapmayı küçük sanır.

İkinci satır aynı kaymayla sıfır üretiyor. Fark tek satırdır: pencere `T - 1440` yerine **son
işlenen andan** başlıyor. Pencere artık saatten değil, işin kendi ilerlemesinden türetiliyor;
kayma pencerenin sonunu oynatsa da başlangıcı bir önceki koşumun bıraktığı yerdir, dolayısıyla
ne boşluk ne örtüşme kalır.

Buradan dersin kuralı çıkar: zamanlanmış tetikleme **işin ne zaman başlayacağını** söyler,
**neyi işleyeceğini** söylememelidir. Neyi işleyeceği veriden okunur. Bu ayrım kurulduğunda üç
kısıt birden kapanır — çift tetikleme yeni iş bulamaz, kaçırılan koşum ertesi koşumda kapanır
ve saat kayması pencereyi bozmaz. Bedeli, her koşumun kendi ilerleme işaretini kalıcı olarak
yazması ve bu yazmanın işle aynı sınırda kesinleşmesi gereğidir; işaret işten önce yazılırsa
kaçan dilim sessizce atlanır, sonra yazılırsa aynı dilim ikinci kez işlenir.

## Özet

- Zamanlanmış tetikleme hizmet olarak alındığında garanti en az bir kezdir: aynı dakikada iki
  tetikleme olabilir ve bu bir arıza değil, ilan edilmiş davranıştır.
- Otuz gecede 31 tetikleme geldi; etkisizlik anahtarı olmadan 3.600 yinelenen fatura yazıldı ve
  iki koşum da hatasız bitti.
- Anahtar eklendiğinde tetikleme sayısı yine 31 kaldı ama yinelenen fatura sıfırlandı:
  tekilleştirilen şey tetikleme değil, yazmadır.
- Kaçırılan koşum telafi edilmez; 2.400 eksik fatura iki satırda da aynı kaldı. Bunu kapatan
  şey anahtar değil, işin "bugünü faturala" yerine "faturalanmamış dönemleri faturala" diye
  yazılmasıdır.
- Pencere tetikleme anından türetildiğinde 36.000 okumanın 648'i hiç işlenmedi, 560'ı iki kez
  işlendi; pencere son işlenen andan türetildiğinde aynı kaymayla iki sayı da sıfır oldu. Kayıp
  rastgele de değildir: kaçan dilim hep gün sınırındadır, yani hep aynı saatte rapor eden
  sayaçlara denk gelir ve toplam üzerinden bakan bir denetimde 648 eksikle 560 fazla birbirini
  kısmen götürür.
- Zamanlanmış tetikleme işin ne zaman başlayacağını söyler; neyi işleyeceğini veriden okumak
  çift tetiklemeyi, kaçırılan koşumu ve saat kaymasını aynı anda kapatır.

## Sonraki Adım

Buraya kadar işlevleri uyandıran her şey içeriden geldi: bir kural, bir kuyruk, bir akış adımı,
bir saat. Ölçüm ağının bir de dışarıya bakan yüzü var — saha ekiplerinin uygulaması, şube
ekranları ve abonelerin kendi tüketimini sorguladığı arayüz. Bu istekler doğrudan işleve
ulaşamaz; arada kimliği doğrulayan, yolu eşleyen ve kısan bir katman durur. Sonraki ders bu
katmanı hizmet olarak ölçer: yapılandırma kalemi sayısı, istek başına ücret, yetkilendirmenin
geçitte yapılmasının işlev çağrısı sayısına etkisi ve geçidin soğuk başlangıç konusunda ne
yapıp ne yapmadığı.
