Skip to main content

Window Servisi

Topoloji referansı: /projects/cinga/backend#sistem-işleyiş-akışı

Window Servisi, synth.ready.v1 eventini tüketip zaman ölçekli istatistik ve trend kayıtlarını energy_windows tablosuna yazan mikroservistir.

Bu servis sentez hesabı yapmaz; yalnızca pencere (fixed + rolling) güncellemelerini yürütür ve analiz katmanını güncel tutar.

Sorumluluk

  • synth.ready.v1 eventini consume etmek
  • Girdi setini Redis device_buffer + DB fallback ile çözmek
  • Sabit pencereleri (1D, 1W, 1M) güncellemek/finalize etmek
  • Kayan pencereleri (1D_Last, 1W_Last, 1M_Last) grid hizalı güncellemek
  • Sonuçları energy_windows tablosuna idempotent upsert etmek
  • Başarıda window.ready.v1, hatada window.failed.v1 üretmek

İşlem Akışı

Girdi Kaynakları

Window servisi girdileri üç kaynaktan çözer:

  1. Redis (device_buffer)
    • synth_buffer (hızlı pencere güncelleme için)
    • raw_buffer (eksik sentez alanı için)
  2. DB (birincil doğrulama/fallback)
    • energy_synth_results
    • gerektiğinde energy_*_measurements
  3. Policy/Config
    • window_types, grid_step, late_tolerance, finalize_delay

Alan çözümleme sırası (deterministic):

  1. synth_buffer
  2. Eksik alan için energy_synth_results
  3. Hâlâ eksikse raw_buffer / energy_*_measurements

Not: Redis miss veya eksik alan durumunda DB fallback zorunludur.

Pencere Tipleri ve Finalize Kuralları

Sabit pencereler:

  • 1D: takvim günü
  • 1W: hafta başlangıç grid'i
  • 1M: ay başlangıç grid'i

Kayan pencereler:

  • 1D_Last: son 24 saat
  • 1W_Last: son 7 gün
  • 1M_Last: son 30 gün

Finalize kuralları:

  • Sabit pencerede window_end geçildikten ve late_tolerance dolduktan sonra finalized=true set edilir.
  • Rolling pencereler varsayılan olarak finalized=false kalır (sürekli güncellenir).
  • Grid hizalama zorunludur (anchor_time), aksi kayıt WINDOW_GRID_MISALIGNED ile reddedilir.

Final Buffer + Hesaplama Politikası (Karar)

Bu sayfada kilitlenen final yaklaşım:

  • Redis raw/synth buffer en fazla 48 saat tutulur.
  • Rolling hesaplar ham uzun geçmişten değil, mümkün olduğunca incremental state + bucket rollup ile yürütülür.
  • p10/p50/p90 yalnızca sabit pencere kapanışında hesaplanır; rolling pencerelerde percentile hesaplanmaz.
  • Sabit pencere hesapları dönem sonunda Window Servisi tarafından tetiklenir:
    • Gün sonu -> 1D
    • Hafta sonu -> 1W
    • Ay sonu -> 1M

Bu modelin sonucu:

  • Redis şişmez (1 ay ham sample tutulmaz)
  • DB her eventte sorgulanmaz
  • Sabit dönem kapanışlarında tek/toplu finalize sorguları ile doğru hesap korunur

Büyük Pencere Hesabı (1W / 1M)

1W ve 1M pencereler mümkün olduğunca rollup ile hesaplanır:

  1. Önce 1D/1D_Last pencerelerini güncelle.
  2. 1W için ilgili 1D kayıtları birleştir.
  3. 1M için ilgili ay içi 1D kayıtları birleştir.
  4. Gap varsa yalnız eksik aralığı ham kaynaktan tamamla.

Bu model DB yükünü azaltır ve büyük pencere hesaplarını stabil tutar.

Hesaplama Yöntemi Akış Diyagramı

energy_windows Persist Tablosu

KolonTipZorunlulukNot
idbigint PKZorunlu
device_idvarchar(21)Zorunlu
variable_idvarchar(30)Zorunlu
window_typevarchar(16)Zorunlufixed/rolling
window_starttimestamptzZorunlu
window_endtimestamptzZorunlu
anchor_timetimestamptzÖnerilengrid anchor
finalizedbooleanZorunlu
calc_versionintegerZorunlu
sample_countintegerZorunlu
expected_sample_countintegerZorunlu
completeness_ratiodouble precisionZorunlu
quality_flagsjsonbZorunlu
sum, sum_sq, min, maxdouble precisionZorunlu
mean, stddevdouble precisionZorunlu
p10, p50, p90double precisionZorunluV1 core
sum_t, sum_v, sum_tv, sum_t2double precisionZorunlutrend altyapısı
slopedouble precisionZorunlu
r2double precisionZorunlu (V1)trend uyum katsayısı
first_value, last_value, delta_valuedouble precisionSayaçta zorunlu
counter_reset_countintegerSayaçta zorunlu
counter_rollover_countintegerSayaçta zorunlu
created_at, updated_attimestamptzZorunlu

Yazım Kuralları

  • Upsert anahtarı: UNIQUE(device_id, variable_id, window_type, window_start)
  • Aynı pencere tekrar işlenirse idempotent upsert uygulanır.
  • finalized=true olmuş sabit pencereye veri değişikliği yalnız Replay Worker tarafından, replay_reason ve replay_job_id alanları ile izlenebilir biçimde izinlidir; normal worker akışında update reddedilir.
  • READ COMMITTED + idempotent upsert varsayılan isolation modelidir.

Yazım Sonrası Akış

DB yazımı tamamlandıktan sonra servis:

  1. Single-writer prensibi ile state patch üretir:
    • window.state.patch.v1 benzeri event ile patch taşınır.
    • State Writer patch'i device_buffer:{device_id}.window_buffer üstüne atomik uygular.
    • Embedded single-writer modunda aynı süreçte doğrudan update yapılabilir.
  2. Başarılıysa window.ready.v1 üretir.
  3. Opsiyonel skor katmanını tetikler.

Başarısızlıkta:

  1. window.failed.v1 üretilir.
  2. Hata kodu log + DLQ akışına taşınır.
  3. Tekrar işleme idempotent pencere anahtarı üstünden yapılır.

Topic ve Event Standardı

Bu sayfada kullanılan standart:

  • Kafka topic: cinga.window.ready, cinga.window.failed
  • Event adı: window.ready.v1, window.failed.v1

Not: Topic taşıma kanalıdır, event payload sözleşmesidir.

Event Sözleşmeleri

window.ready.v1

{
"event": "window.ready.v1",
"meta": {
"schema_version": 1,
"trace_id": "9f3f...",
"producer_service": "window-service",
"produced_at": "2026-03-11T15:22:15.040Z",
"process_ms": 27
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"data": {
"calc_version": 1,
"window_types_updated": [
"1D_Last",
"1W_Last",
"1M_Last"
],
"finalized_windows": [
"1D"
]
},
"error": null
}

window_types_updated enum kümesi:

  • 1D
  • 1W
  • 1M
  • 1D_Last
  • 1W_Last
  • 1M_Last

window.failed.v1

{
"event": "window.failed.v1",
"meta": {
"schema_version": 1,
"trace_id": "9f3f...",
"producer_service": "window-service",
"produced_at": "2026-03-11T15:22:15.070Z",
"process_ms": 27
},
"context": {
"device_id": "400000011D081B70",
"stream_id": 9823412
},
"error": {
"failed_stage": "window",
"error_code": "WINDOW_DB_WRITE_FAIL",
"error_message": "energy_windows upsert failed",
"retryable": true,
"failed_at": "2026-03-11T15:22:15Z"
}
}

retryable karar matrisi:

  • WINDOW_DB_WRITE_FAIL: true
  • WINDOW_INPUT_TRANSIENT: true (geçici state/lag)
  • WINDOW_GRID_MISALIGNED: false
  • WINDOW_POLICY_INVALID: false
  • WINDOW_INPUT_MISSING: false

Hata Kodları

  • WINDOW_INPUT_MISSING
  • WINDOW_INPUT_TRANSIENT
  • WINDOW_POLICY_INVALID
  • WINDOW_GRID_MISALIGNED
  • WINDOW_DB_WRITE_FAIL

İstatistik Field Hesaplama Rehberi

Aşağıdaki bölümde V1 alanları için nedir / nasıl hesaplanır / neye ihtiyaç duyar formatı kullanılmıştır.

V1 (Aktif)

1) Kalite Alanları
  • sample_count
    • Nedir: Pencereye giren geçerli örnek sayısı.
    • Nasıl hesaplanır: Validasyon geçen örneklerin adedi.
    • Neye ihtiyaç duyar: window_start, window_end, valid örnek listesi.
  • expected_sample_count
    • Nedir: Bu pencere için beklenen teorik örnek sayısı.
    • Nasıl hesaplanır: window_duration / sample_period.
    • Neye ihtiyaç duyar: Pencere süresi, cihaz örnekleme periyodu.
  • completeness_ratio
    • Nedir: Veri doluluk oranı.
    • Nasıl hesaplanır: sample_count / max(expected_sample_count, 1).
    • Neye ihtiyaç duyar: sample_count, expected_sample_count.
  • quality_flags
    • Nedir: Gap/reset/rollover/outlier gibi kalite işaretleri.
    • Nasıl hesaplanır: Kural kontrollerinden üretilen flag seti (jsonb).
    • Neye ihtiyaç duyar: Ham/sentez akışı kalite olayları, policy eşikleri.
2) Dağılım Alanları
  • sum
    • Nedir: Toplam değer.
    • Nasıl hesaplanır: Σ x_i.
    • Neye ihtiyaç duyar: Pencere örnekleri.
  • sum_sq
    • Nedir: Kareler toplamı.
    • Nasıl hesaplanır: Σ x_i^2.
    • Neye ihtiyaç duyar: Pencere örnekleri.
  • min, max
    • Nedir: Pencere içi alt/üst uç.
    • Nasıl hesaplanır: min(x_i), max(x_i).
    • Neye ihtiyaç duyar: Pencere örnekleri.
  • mean
    • Nedir: Ortalama.
    • Nasıl hesaplanır: sum / max(sample_count, 1).
    • Neye ihtiyaç duyar: sum, sample_count.
  • stddev
    • Nedir: Standart sapma.
    • Nasıl hesaplanır: sqrt(max(sum_sq/n - mean^2, 0)), n=sample_count.
    • Neye ihtiyaç duyar: sum_sq, sample_count, mean.
  • p10, p50, p90
    • Nedir: Alt/orta/üst percentile göstergeleri.
    • Nasıl hesaplanır: Sıralı veri üzerinden percentile fonksiyonu (veya sketch).
    • Neye ihtiyaç duyar: Pencere örnek dağılımı (ham veya sketch state).
3) Trend Alanları
  • sum_t
    • Nedir: Zaman indeks toplamı.
    • Nasıl hesaplanır: Σ t_i.
    • Neye ihtiyaç duyar: Grid-hizalı zaman indeksleri.
  • sum_v
    • Nedir: Değer toplamı (trend hesabı için).
    • Nasıl hesaplanır: Σ v_i.
    • Neye ihtiyaç duyar: Pencere değerleri.
  • sum_tv
    • Nedir: Zaman*değer toplamı.
    • Nasıl hesaplanır: Σ (t_i * v_i).
    • Neye ihtiyaç duyar: Zaman indeksleri + değerler.
  • sum_t2
    • Nedir: Zaman kare toplamı.
    • Nasıl hesaplanır: Σ (t_i^2).
    • Neye ihtiyaç duyar: Zaman indeksleri.
  • slope
    • Nedir: Lineer trend eğimi.
    • Nasıl hesaplanır: (n*sum_tv - sum_t*sum_v) / max(n*sum_t2 - sum_t^2, EPS).
    • Neye ihtiyaç duyar: n, sum_t, sum_v, sum_tv, sum_t2.
  • r2
    • Nedir: Trend uyum katsayısı.
    • Nasıl hesaplanır: 1 - SSE/SST (SST=0 ise r2=1).
    • Neye ihtiyaç duyar: Regresyon tahmin hataları veya eşdeğer ara toplamlar.
4) Sayaç Alanları (Counter Variables)
  • first_value
    • Nedir: Pencere başlangıcındaki sayaç.
    • Nasıl hesaplanır: Pencereye giren ilk geçerli örnek.
    • Neye ihtiyaç duyar: Zaman sıralı sayaç örnekleri.
  • last_value
    • Nedir: Pencere sonundaki sayaç.
    • Nasıl hesaplanır: Pencereye giren son geçerli örnek.
    • Neye ihtiyaç duyar: Zaman sıralı sayaç örnekleri.
  • delta_value
    • Nedir: Pencere net tüketim/değişim değeri.
    • Nasıl hesaplanır: last_value - first_value (reset/rollover düzeltmeleri policy’ye göre).
    • Neye ihtiyaç duyar: first_value, last_value, reset/rollover tespiti.
  • counter_reset_count
    • Nedir: Sayaç reset sayısı.
    • Nasıl hesaplanır: Ani negatif büyük sıçrama + reset pattern eşleşmesi.
    • Neye ihtiyaç duyar: Ardışık sayaç örnekleri, reset eşik/policy.
  • counter_rollover_count
    • Nedir: Sayaç taşma (rollover) sayısı.
    • Nasıl hesaplanır: Modül üst sınırını aşan geçişlerin tespiti.
    • Neye ihtiyaç duyar: Sayaç bit genişliği/modulus bilgisi, ardışık örnekler.

V2 (Deferred)

V2’de Eklenecek İstatistikler
  • Geniş percentile seti: p01, p05, p95, p99
  • Ek regresyon alanı: intercept
  • Geniş event/maruziyet alanları (threshold süreleri, event breakdown)

Index

  • UNIQUE(device_id, variable_id, window_type, window_start)
  • (device_id, variable_id, window_type, window_end DESC)
  • (device_id, window_type, window_start DESC)

Çıktı

Window Servisinin çıktısı:

  • energy_windows tablosunda kalıcı pencere verisi
  • Redis window_buffer state güncellemesi (state-writer üzerinden)
  • Kafka'da window.ready.v1 (veya hata durumunda window.failed.v1)