Hacker DirectoryHacker Directory
Öğrenmeye devam et
ENHTML kaydet ↓

WEB / WEB-19.02

Queue, producer, consumer ve worker

Public note için background indexing job’u hazırlanır. Queue teslimi, DB sonucu ve acknowledgement farklı adımlarda oluşur.

CORE · RED · BLUE · ARTIFACT · PRACTICE

1. Core · Mekanizma

Hareket olmadan bütün senaryoları oku

Commit, sonra ack

  1. Job hazırlandı

    Producer, job-note-1 için jobId, kind=index-public-note ve noteId=tea verisini hazırlar. Queue ve worker bu örnekte yerel adapter’lardır; henüz publication, delivery veya business commit yok.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Teslim yok
    Business DB
    Result=0 / marker=0
  2. Queue işi kabul etti

    Job pending listesine alınır. Kabul sonucu business işlemin tamamlandığını veya gerçek broker confirm alındığını göstermez.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=1 / inflight=0
    Worker
    Teslim yok
    Business DB
    Result=0 / marker=0
  3. Worker teslim aldı

    Job pending’den inflight’a geçer ve worker’a verilir. Sahne yerel queue teslimini gösterir.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Job-note-1 / delivery=1
    Business DB
    Result=0 / marker=0
  4. Job verisi kontrol edildi

    Worker kind, noteId ve jobId alanlarını beklenen biçime göre kontrol eder. Mesaj içeriği kod olarak çalıştırılmaz.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Job schema kabul edildi
    Business DB
    Result=0 / marker=0
  5. Sonuç ve marker commit edildi

    Business result ile processed marker aynı DB transaction’da commit edilir. Queue’nun inflight state’i ayrı kalır; ack henüz uygulanmamıştır.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Job schema kabul edildi
    Business DB
    Result=1 / marker=1
  6. Ack hazırlanıyor

    Worker commit sonucundan sonra ack vermeyi seçer. Ack işlemi DB commit’ini kendiliğinden doğrulamaz.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Sonuç committed / ack hazır
    Business DB
    Result=1 / marker=1
  7. Ack uygulandı

    Queue ack’i uygular ve inflight kaydını kaldırır. Bu değişim business result oluşturmaz; DB sonucu ayrı okunmalıdır.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Sonuç committed / ack hazır
    Business DB
    Result=1 / marker=1
  8. İş sonucu ve teslim ayrıldı

    Kayıt business result ile queue lifecycle’ını ayrı gösterir. HTTP caller’ın sonucu aldığı bu sahneden çıkmaz.

    Producer
    Business result hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Sonuç committed / ack hazır
    Business DB
    Result=1 / marker=1

Commit/ack gap

  1. Job hazırlandı

    Producer, bilinen public note job’unu mesaj verisi olarak hazırlar. Queue henüz bu işi kabul etmemiştir.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Teslim yok
    Business DB
    Result=0 / marker=0
  2. Queue işi kabul etti

    Job pending listesine alınır. Kabul sonucu business işlemin tamamlandığını veya gerçek broker confirm alındığını göstermez.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=1 / inflight=0
    Worker
    Teslim yok
    Business DB
    Result=0 / marker=0
  3. Worker teslim aldı

    Job pending’den inflight’a geçer ve worker’a verilir. Sahne yerel queue teslimini gösterir.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Job-note-1 / delivery=1
    Business DB
    Result=0 / marker=0
  4. Sonuç ve marker commit edildi

    Business result ile processed marker aynı DB transaction’da commit edilir. Queue’nun inflight state’i ayrı kalır; ack henüz uygulanmamıştır.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Job-note-1 / delivery=1
    Business DB
    Result=1 / marker=1
  5. Worker durdu, job geri alındı

    Örnekte worker ack vermeden durur. Job tekrar pending olur; daha önceki business commit geri alınmaz.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=1 / inflight=0
    Worker
    Job-note-1 / delivery=1
    Business DB
    Result=1 / marker=1
  6. Aynı job yeniden teslim edildi

    Job-note-1 ikinci delivery ile worker’a gelir. Business job ID aynıdır; teslim instance’ı farklıdır.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Job-note-1 / delivery=2
    Business DB
    Result=1 / marker=1
  7. Committed marker bulundu

    Marker lookup önceki sonucu bulur ve ikinci business effect atlanır. Result row sayısı 1 kalır; dış effect’ler bu kontrolün kapsamında değildir.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Job-note-1 / delivery=2
    Business DB
    Marker bulundu / result=1 korundu
  8. İkinci teslim ack aldı

    Worker korunmuş business sonuçtan sonra ack verir ve inflight temizlenir. Bu örnek bütün sistem için exactly-once garantisi sağlamaz.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Job-note-1 / delivery=2
    Business DB
    Marker bulundu / result=1 korundu

Early ack stop

  1. Job hazırlandı

    Producer, bilinen public note job’unu mesaj verisi olarak hazırlar. Queue henüz bu işi kabul etmemiştir.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Teslim yok
    Business DB
    Result=0 / marker=0
  2. Queue işi kabul etti

    Job pending listesine alınır. Kabul sonucu business işlemin tamamlandığını veya gerçek broker confirm alındığını göstermez.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=1 / inflight=0
    Worker
    Teslim yok
    Business DB
    Result=0 / marker=0
  3. Worker teslim aldı

    Job pending’den inflight’a geçer ve worker’a verilir. Sahne yerel queue teslimini gösterir.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Job-note-1 / delivery=1
    Business DB
    Result=0 / marker=0
  4. Commit öncesinde ack

    Worker business commit olmadan ack vermeyi seçer. Sonraki durma halinde queue ile iş sonucu arasındaki boşluk burada açılır.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=1
    Worker
    Ack hazır / business result yok
    Business DB
    Result=0 / marker=0
  5. Ack uygulandı

    Queue ack’i uygular ve inflight kaydını kaldırır. Bu değişim business result oluşturmaz; DB sonucu ayrı okunmalıdır.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Ack hazır / business result yok
    Business DB
    Result=0 / marker=0
  6. İşlem öncesinde worker durdu

    Örnekte worker business operation’dan önce durur. Queue’nun boşalması işin tamamlandığını göstermez.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Business commit öncesi durdu
    Business DB
    Result=0 / marker=0
  7. Business result yok

    Bağımsız lookup result row=0 ve marker=0 görür. Önceden ack alan job artık pending değildir.

    Producer
    Job-note-1 hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Business commit öncesi durdu
    Business DB
    Result=0 / marker=0

Outbox relay gap

  1. Update ve event aynı transaction’da

    Producer note update ile event intent’i aynı DB transaction içinde hazırlamayı seçer.

    Producer
    Producer transaction hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Teslim yok
    Business DB
    Note version=1 / outbox=0
  2. İki kayıt henüz pending

    Note version=2 ve outbox row aynı transaction’da bekler. Relay, commit edilmemiş event’i yayınlamaz.

    Producer
    Producer transaction hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Teslim yok
    Business DB
    Note=2 pending / outbox=1 pending
  3. İki kayıt birlikte commit edildi

    COMMIT, note ve outbox kaydını görünür yapar. Queue’ya publish henüz yapılmamıştır.

    Producer
    Producer transaction hazır
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Teslim yok
    Business DB
    Note=2 committed / outbox=1 pending
  4. Relay committed event’i okudu

    Relay pending outbox row’u bağımsız read ile bulur ve bilinen job mesajını hazırlar.

    Producer
    Relay job-note-1 seçti
    Yerel queue
    Pending=0 / inflight=0
    Worker
    Teslim yok
    Business DB
    Note=2 committed / outbox=1 pending
  5. Queue publish’i kabul etti

    Queue job’u pending olarak kabul eder. Database’deki sent marker henüz değişmez.

    Producer
    Relay job-note-1 seçti
    Yerel queue
    Pending=1 / inflight=0
    Worker
    Teslim yok
    Business DB
    Note=2 committed / outbox=1 pending
  6. Publish ile marker arasında durma

    Relay publish sonrasında, sent marker güncellenmeden durur. Queue kabulü bilir; database kaydı hâlâ pending görünür.

    Producer
    Sent marker öncesi durdu
    Yerel queue
    Pending=1 / inflight=0
    Worker
    Teslim yok
    Business DB
    Note=2 committed / outbox=1 pending
  7. Outbox hâlâ pending

    Bağımsız read note version=2 ve sent=false olan bir outbox row görür. Bu kayıt hiç publish yapılmadığını kanıtlamaz.

    Producer
    Sent marker öncesi durdu
    Yerel queue
    Pending=1 / inflight=0
    Worker
    Teslim yok
    Business DB
    Note=2 / outbox=1 / sent=false
  8. Retry tekrar publish etti

    Relay aynı job’u yeniden queue’ya verir. Aynı business effect’i tekrarlamamak için consumer’ın job identity ve idempotency kontrolü gerekir.

    Producer
    Sent marker öncesi durdu
    Yerel queue
    Pending=2 / aynı job ID
    Worker
    Teslim yok
    Business DB
    Note=2 / outbox=1 / sent=false

ROLLER · STATE · VERİ AKIŞI

Queue işi ne zaman, kim için saklar?

Producer bir iş tanımını message olarak hazırlar. Atlas’ta job-note-1, public tea notunun indexlenmesini ister. Queue bekleyen işi tutar; consumer delivery’yi alır; worker application logic’i çalıştırır. Bu roller aynı process içinde veya ayrı service’lerde bulunabilir. Buradaki worker bir background application bileşenidir; browser Web Worker veya Service Worker API’si değildir. Queue’ya iş koymak, business sonucun oluştuğu veya HTTP caller’ın sonucu aldığı anlamına gelmez.

Background job, uzun veya ertelenebilir işi request lifecycle’dan ayırabilir. Accepted/pending yanıtı kullanıcıya işin devredildiğini anlatır; scheduled iş daha sonra başarısız da olabilir. Concurrency, capacity ve prefetch, bir worker’ın kaç outstanding delivery tuttuğunu etkiler. Evrensel tuning değeri yoktur. Atlas örneği tek job’u finite pending/inflight list’leriyle izler; gerçek broker veya parallel worker ölçümü yapmaz.

Message jobId, kind ve noteId alanlarını taşır. Application’ın seçtiği jobId business idempotency kimliğidir. RabbitMQ delivery tag ise channel içinde bir delivery’yi tanımlar; job kimliğiyle aynı şey değildir. Aynı job tekrar teslim edildiğinde delivery kimliği değişebilir. Message’ın bilinen schema ve purpose’a uyması gerekir; payload’ın varlığı permission kararı değildir ve içeriği code olarak çalıştırılmaz.

Ack, commit ve duplicate hangi sınırı geçer?

Publisher confirm, producer’ın broker’a publication sonucuyla ilgilidir. Consumer acknowledgement ise consumer delivery için ayrı bir sınırdır. Hiçbiri kendiliğinden application’ın business transaction sonucunu denetlemez. Atlas’ın manual-ack politikası önce result ile processed-job marker’ını aynı SQLite transaction’ında commit eder, sonra queue adapter’a ack verir. Ack, queue’nun inflight state’ini kaldırır. Erken ack verilip worker result’u kaydetmeden durursa queue artık işin beklediğini bilmez.

Commit başarılı olmuşken ack henüz görülmeden consumer durabilir. RabbitMQ manual acknowledgement akışında channel/connection kapanması unacked delivery’leri yeniden queue’ya alabilir. Atlas bunun küçük bir yerel modelini gösterir: aynı job ikinci kez gelir, committed marker bulunduğu için ikinci business effect üretilmez ve yeni delivery ack edilir. İki delivery, iki business effect değildir. Result ve marker aynı transaction içindedir; email, file veya dış API effect’i bu SQL sınırına otomatik katılmaz.

Producer’ın database update’i ile queue publish’ı da farklı owner’lara write’tır. Outbox pattern business row ve pending event row’unu aynı database transaction’ında saklar; relay daha sonra event’i publish eder. Publish ile sent marker arasında durma olursa aynı event tekrar publish edilebilir. Outbox bu nedenle consumer idempotency ihtiyacını kaldırmaz. Örneğin yerel relay state’i ve SQLite commit/rollback’i izlenir; universal exactly-once sonucu çıkarılmaz.

2. Red · Güven ve etki

Hareket olmadan bütün senaryoları oku

Erken ack

  1. İş teslim alındı

    Worker job-note-1 işini teslim almış, fakat business result henüz commit edilmemiş. Delivery bilgisi result satırının yerine geçmez.

    Delivery / relay
    Delivery alındı; ack bekliyor
    Business database
    Business commit bekliyor
    Sonuç beklentisi
    Final sonuç bekliyor
  2. Ack business commit’ten önce

    Bu dalda queue önce ack’i uyguluyor. Kendi outstanding state’ini kaldırabiliyor; database’de result olup olmadığını bu kararın parçası olarak denetlemiyor.

    Delivery / relay
    queueOutstanding=0
    Business database
    Business commit bekliyor
    Sonuç beklentisi
    Queue boş; sonuç henüz bilinmiyor
  3. Worker commit öncesinde durdu

    Örnekte worker, ack sonrasında ve business commit öncesinde duruyor. Database sonucu oluşmuyor; queue’nun önceki ack bilgisi geri alınmış sayılmaz.

    Delivery / relay
    queueOutstanding=0
    Business database
    resultRows=0
    Sonuç beklentisi
    Worker commit öncesinde durdu
  4. Sonucu bağımsız kayıttan oku

    Result owner’da resultRows=0 görülüyor. Queue boşluğu ile bu alan birlikte okunduğunda “iş tamamlandı” yorumu desteklenmiyor.

    Delivery / relay
    queueOutstanding=0
    Business database
    resultRows=0
    Sonuç beklentisi
    completedBusiness=false
  5. Queue completion’ı success’e çevirme

    Ack, bu delivery için queue lifecycle’ını bitirmiştir. Business sonucunun oluştuğu başka bir owner’dan doğrulanmalıdır; burada completedBusiness=false.

    Delivery / relay
    queueOutstanding=0
    Business database
    resultRows=0
    Sonuç beklentisi
    completedBusiness=false
  6. Düzeltmenin ölçütü sonucu da kapsar

    Normal dalda result ve processed marker aynı transaction’da commit edilir, ardından ack gelir. Kabul ölçütü yalnız boş queue değil, aynı job için business commit ve doğru ack sırasıdır.

    Delivery / relay
    Erken ack kaydı var
    Business database
    resultRows=0
    Sonuç beklentisi
    Commit ve ack ayrı doğrulanır

Relay aralığı

  1. Not ve event birlikte commit

    Producer, noteVersion=2 ile pendingRows=1 değerlerini aynı database transaction’ında kaydediyor. Bu event’in publish edildiğini henüz söylemiyor.

    Delivery / relay
    Publish sonucu bekliyor
    Business database
    noteVersion=2 / pendingRows=1
    Sonuç beklentisi
    Database’de intent commit edildi
  2. Relay publish yaptı

    publishEventsBeforeSentMarker=1: relay bir publish gerçekleştirmiş. Database’de sent marker henüz güncellenmediği için iki owner aynı tamamlanma bilgisini taşımıyor.

    Delivery / relay
    publishEvents=1
    Business database
    sentMarked=false
    Sonuç beklentisi
    Publish var; marker yok
  3. Publish ile sent marker arasında duruş

    Relay publish sonrasında sent kaydını yazamadan durabilir. sentMarked=false değeri, publish’ın hiç gerçekleşmediği anlamına gelmez.

    Delivery / relay
    publishEvents=1 / relay stopped
    Business database
    sentMarked=false
    Sonuç beklentisi
    Publication cannot be inferred from sent=false
  4. Retry hangi bilgiyi görüyor?

    Retry database’de pending event’i görüyor. Daha önce publish edilmiş aynı job için yeni bir publish yapılması mümkün; outbox bu belirsizliği tek başına kaldırmıyor.

    Delivery / relay
    duplicatePublishPossible=true
    Business database
    sentMarked=false
    Sonuç beklentisi
    Aynı job identity korunmalı
  5. Publish sayısı iki oldu

    publishEventsAfterRetry=2. İki publish event’i, iki business effect gerçekleştiğini göstermez; consumer’ın aynı job’u nasıl değerlendirdiği ayrıca gerekir.

    Delivery / relay
    publishEventsAfterRetry=2
    Business database
    sameDatabaseTransaction=true
    Sonuç beklentisi
    Publish count != business effect count
  6. Outbox ile idempotency farklı işleri çözer

    Outbox, business update ile event intent’ini aynı commit’e bağlar. Consumer idempotency ise aynı operation’ın tekrar tesliminde ikinci effect’i önler. External effect’ler bu SQLite transaction’ına kendiliğinden katılmaz.

    Delivery / relay
    publishEventsAfterRetry=2
    Business database
    externalEffectsInSqlTransaction=false
    Sonuç beklentisi
    Consumer idempotency ayrıca gerekir

VARSAYIM · SINIR · KONTROL

Queue state business state değildir

Accepted, inflight, business committed ve queue acked ayrı durumlardır. Erken ack dalında queueOutstanding=0 olmasına rağmen resultRows=0 kalır. Boş queue, tamamlanmış business işi kanıtlamaz. “Done” mesajı veya sayaç hangi owner’ın hangi işleminin bittiğini açıklamıyorsa öğrenci gerçek completion sınırını kaybeder.

Commit-before-ack dalında resultRows=1 ile inflight delivery birlikte bulunabilir. Worker’ın bu arada durması yeniden teslim ihtimalini bırakır. Artifact aynı job için deliveries=2 ve businessEffects=1 ayrımını görünür tutar. Bu ilişkinin dayanağı selected job identity ve committed marker’dır; herhangi bir queue ürününün etiketi değildir.

Idempotency marker hangi işi kapsar?

Marker jobId üzerinden business database’de tutulur. Marker ve result farklı transaction’larda yazılsaydı aradaki failure yeni bir gap yaratabilirdi. Örnekte ikisi aynı transaction’da hazırlanır; rollback dalında independent read ikisinin de olmadığını gösterir. Marker seçilen job kimliğini kapsar. Başka operation purpose veya external effect için aynı korumanın geçerli olduğu ayrıca gösterilmelidir.

Pending outbox row henüz publish edilmemiş olabilir; relay’in sent kaydı geciktiyse publish yapılmış da olabilir. Bu yüzden sent=false, “hiç consumer almadı” kanıtı değildir. Bilgi publication owner’ında ve business owner’ında farklı anlarda güncellenir. İnceleme aynı event için publish, sent marker, delivery ve committed effect observation’larını ayrı takip eder.

3. Blue · Güvenli geliştirme ve savunma

Hareket olmadan bütün senaryoları oku

Yeniden teslim

  1. İş kimliğini sabitle

    Delivery sayısını yerel queue adapter’ı, result ile processed marker’ı bağımsız SQLite SELECT üretir. Aynı jobId ile eşleştirilen bu alanlar broker telemetry’si veya yakalanmış paket değildir. job-note-1, application’ın seçtiği business job identity’si. Queue delivery identity’si ile aynı alan değildir; yeniden teslimde önce aynı job’un geldiği doğrulanır.

    Delivery gözlemi
    jobId=job-note-1
    Result ve marker
    Result henüz okunmadı
    Kanıt yorumu
    Correlation pending
  2. Commit edilen marker’ı oku

    Normal işleme result ve processed marker birlikte commit edilmiştir. Marker, bu job için mevcut business sonucu tarif eder; yalnız worker’ın “başladım” mesajı değildir.

    Delivery gözlemi
    jobId=job-note-1
    Result ve marker
    resultRows=1 / processedRows=1
    Kanıt yorumu
    Bu job için commit edilmiş sonuç
  3. Delivery sayısı iki

    redelivery.deliveries=2 ve sameJobId=true. İki teslim, iki farklı business operation olduğunu göstermiyor.

    Delivery gözlemi
    deliveries=2 / sameJobId=true
    Result ve marker
    resultRows=1 / processedRows=1
    Kanıt yorumu
    Aynı operation yeniden geldi
  4. İkinci effect oluşmadı

    businessEffects=1, processedMarkers=1 ve duplicateResultInserted=false birlikte okunur. Consumer ikinci teslimde mevcut marker’ı kullanmış; result yeniden eklenmemiş.

    Delivery gözlemi
    deliveries=2 / sameJobId=true
    Result ve marker
    businessEffects=1 / duplicateResultInserted=false
    Kanıt yorumu
    Aynı job’un ikinci effect’i önlendi
  5. Ack sonucu ayrıca görüldü

    inflightAfterAck=0, queue tarafındaki son state’tir. Database’de tek result bulunması ile aynı alan değildir; her iki owner ayrı doğrulanır.

    Delivery gözlemi
    inflightAfterAck=0
    Result ve marker
    businessEffects=1 / processedMarkers=1
    Kanıt yorumu
    Queue ve database sonuçları ayrı
  6. Doğrulanan kapsamı koru

    Bu yerel örnekte aynı job’un iki teslimi tek business effect bırakıyor. Bütün broker’lar, parallel worker’lar veya dış API effect’leri için universal exactly-once sonucu çıkarılmaz.

    Delivery gözlemi
    deliveries=2
    Result ve marker
    businessEffects=1 / processedMarkers=1
    Kanıt yorumu
    universalExactlyOnce=false

Rollback intent

  1. Commit ve rollback örneklerini ayır

    Delivery sayısını yerel queue adapter’ı, result ile processed marker’ı bağımsız SQLite SELECT üretir. Aynı jobId ile eşleştirilen bu alanlar broker telemetry’si veya yakalanmış paket değildir. Outbox kaydı iki transaction sonucu içeriyor. Başlık değişikliği ile event intent’inin aynı transaction içinde olup olmadığını bu iki dalı karşılaştırarak incelersin.

    Delivery gözlemi
    Publish henüz incelenmedi
    Result ve marker
    Commit / rollback dalları
    Kanıt yorumu
    Atomic intent henüz doğrulanmadı
  2. Commit dalında iki sonuç birlikte

    Commit dalında noteVersion=2 ve pendingRows=1. Yeni not revision’ı ile publish intent’i aynı database sınırında kalıyor.

    Delivery gözlemi
    Publish henüz incelenmedi
    Result ve marker
    commit: noteVersion=2 / pendingRows=1
    Kanıt yorumu
    sameDatabaseTransaction=true
  3. Rollback dalında event çıkmıyor

    Rollback dalında noteVersion=1 ve pendingRows=0. Başarısız transaction, yeni revision veya committed pending event bırakmıyor.

    Delivery gözlemi
    Publish henüz incelenmedi
    Result ve marker
    rollback: noteVersion=1 / pendingRows=0
    Kanıt yorumu
    Database’de intent rollback gözlendi
  4. Bu kanıt hangi soruyu cevaplıyor?

    Karşılaştırma business row ile event intent’inin birlikte commit/rollback olduğunu destekler. Queue consumer’ın tamamlandığını veya caller’ın sonucu gördüğünü göstermez.

    Delivery gözlemi
    Consumer sonucu bilinmiyor
    Result ve marker
    sameDatabaseTransaction=true
    Kanıt yorumu
    Intent atomicity != end-to-end completion
  5. Relay başka bir owner sınırı

    Relay daha sonra pending event’i publish eder. Publish sonucu ile sent marker arasında bir aralık bulunabileceği için önceki transaction’ın atomikliği bütün zinciri atomik yapmaz.

    Delivery gözlemi
    duplicatePublishPossible=true
    Result ve marker
    sameDatabaseTransaction=true
    Kanıt yorumu
    Consumer sonucu bilinmiyor
  6. Kabul ölçütünü katmanlara böl

    Database intent’i, publish gözlemi, aynı job için consumer result ve ack ayrı ölçütlerdir. Bir ölçütün başarılı olması, diğer alanlar eksikken bütün işi başarılı saydırmaz.

    Delivery gözlemi
    Publish kanıtı gerekir
    Result ve marker
    Intent’in atomikliği gözlendi
    Kanıt yorumu
    Result ve ack için ayrı kanıt gerekir

UYGULAMA · GÜVENLİK KONTROLÜ · DOĞRULAMA

Completion ve retry policy açık olsun

Delivery sayısını yerel queue adapter’ı, result ile processed marker’ı bağımsız SQLite SELECT üretir. Aynı jobId ile eşleştirilen bu alanlar broker telemetry’si veya yakalanmış paket değildir. Worker, kind=index-public-note ve noteId=tea için bilinen message schema’sını değerlendirir. Delivery alınca inflight state oluşur; business commit sonrası manual ack bunu kaldırır. Independent SELECT ile result ve processed marker’ın aynı job’a ait olduğu incelenir. Queue state’ini database sonucu yerine kullanma; code execution ile message parsing’i de karıştırma.

Commit sonrası, ack öncesi durma dalında ikinci delivery aynı jobId’yi taşır. Worker committed marker’ı bulduğunda yeni result yazmaz. Ack intent’i ile broker’ın ack’i alması gerçek network’te ayrı gözlemlerdir. Atlas’ın yerel adapter’ı method return’de kendi state’ini değiştirir; bunu yakalanmış network packet gibi çizmez. Gerçek broker için channel ve recovery davranışı ayrı doğrulanır.

Outbox ve bounded work farklı kontrollerdir

Producer note update’i ile outbox event’ini aynı transaction’da commit eder; rollback olmuş iş yeni event bırakmaz. Relay yalnız committed pending row’ları publish eder. Publish sonrası sent marker gecikmesi duplicate bırakabileceğinden consumer aynı job’un effect’ini ayrıca sınırlar. External effect’i bu transaction’a dahil etmek gerekiyorsa onun owner’ı ve failure sınırı da tasarıma eklenir.

Worker capacity, retry sayısı ve failed-job handling product policy’sidir. Sonsuz retry’nin yerine kaç deneme yapılacağı, hangi hata için yeniden deneneceği ve hangi final durumun kullanıcıya bildirileceği açık olmalıdır. Ack transaction’ın yerine geçmez; queue durability de business result durability’sini kanıtlamaz. Aynı job için kabul, delivery, commit ve notification ayrı sonuçlar olarak kalır.

ŞİMDİ VAKAYA UYGULA

Publish, delivery, business commit ve ack hangi owner’ın tamamlanmasıdır?

Atlas, public tea notunu indexlemek için job-note-1 işini hazırlıyor. Queue bu işi artık outstanding saymayabilir; buna rağmen bağımsız result kaydında hiçbir satır bulunmayabilir. İşin teslim edilmesi ile işin sonucu ayrı izlenir.

Vakadaki accepted, delivery ve committed effect kayıtlarını farklı owner’lar üzerinden oku. Caller’ın bilinmeyen sonucunu business rollback olarak yeniden adlandırma.

Bağlı vaka dosyasını aç ↗

ÖRNEĞİ BİRLİKTE OKUYALIM

Public note job/delivery/outbox ledger

Bir alan seç; hangi sonucu desteklediğini ve nerede yetersiz kaldığını incele.

Ham kaydı ve alan açıklamalarını oku
{
  "job": {
    "jobId": "job-note-1",
    "kind": "index-public-note",
    "noteId": "tea",
    "dataIsCode": false
  },
  "normal": {
    "pendingAfterPublish": 1,
    "inflightAfterDelivery": 1,
    "resultRowsAfterCommit": 1,
    "processedRowsAfterCommit": 1,
    "pendingAfterAck": 0,
    "inflightAfterAck": 0,
    "publisherConfirmIsBusinessResult": false
  },
  "redelivery": {
    "deliveries": 2,
    "businessEffects": 1,
    "processedMarkers": 1,
    "sameJobId": true,
    "duplicateResultInserted": false,
    "inflightAfterAck": 0
  },
  "earlyAck": {
    "queueOutstanding": 0,
    "resultRows": 0,
    "completedBusiness": false,
    "failure": "injected stop after ack before business commit"
  },
  "outbox": {
    "commit": {
      "noteVersion": 2,
      "pendingRows": 1
    },
    "rollback": {
      "noteVersion": 1,
      "pendingRows": 0
    },
    "relay": {
      "publishEventsBeforeSentMarker": 1,
      "sentMarked": false,
      "duplicatePublishPossible": true,
      "publishEventsAfterRetry": 2
    },
    "sameDatabaseTransaction": true
  },
  "limits": {
    "brokerExecuted": false,
    "simulation": "own finite Python queue adapter + sqlite3 business/outbox state",
    "externalEffectsInSqlTransaction": false,
    "universalExactlyOnce": false
  },
  "selector": {
    "language": "XPath",
    "xml": "<audit><job queueAcked=\"true\" businessCommitted=\"true\"/></audit>",
    "xpath": "count(/audit/job[@queueAcked='true' and @businessCommitted='false'])",
    "expected": 0,
    "positiveFixtureXml": "<audit><job queueAcked=\"true\" businessCommitted=\"false\"/></audit>",
    "positiveExpected": 1,
    "scope": "Only authored protocol-decision observations, not product log field names or a live HTTP capture.",
    "missingFieldBehavior": "Missing observation is insufficient evidence; zero matches is not proof of correct runtime behavior."
  }
}
job
Known public-note job schema; inert data.
normal/redelivery/earlyAck
Business result ile delivery/ack ayrı outcomes.
outbox
Same database intent commit ve finite relay gap.
selector
Synthetic early acknowledgement boundary.

Own queue simulation ve local SQLite only; real RabbitMQ/Kafka/SQS, parallel workers veya universal exactly-once testi değildir.

İki yanlış kanı

Queue ack veya publisher confirm business transaction’ın commit’ini kanıtlar.

Bunlar ayrı delivery/publication scopes’tur; business result owner’ı ayrıca doğrulanır.

Outbox varsa duplicate job veya idempotency düşünmeye gerek yoktur.

Relay publish/sent gap’i duplicates bırakabilir; selected consumer business effect’i kendi transaction boundary’sinde idempotent tutar.

SIRA SENDE

Bu hikâyeyi sen çöz.

Sonucu tahmin et, kanıtın sınırını bul ve nedenini kendi cümlenle anlat.

Queue için erken ACK verildi, fakat resultRows=0. Job’ın business işlemi tamamlanmış mıdır?

  1. Evet. Queue ACK bütün business effect’lerini commit eder.
  2. Hayır. outstanding=0 olsa da completedBusiness=false.
Gerekçeli cevabı oku

Hayır. outstanding=0 olsa da completedBusiness=false. — ACK, broker’daki bekleyen delivery’yi bitirir. Bu örnekte business commit yapılmadan durulduğu için sonuç üretilmemiştir.

Delivery sayısı 2 iken businessEffects=1 olması nasıl mümkün?

Dersten seçilen artifact alanları; öğretim örneği

redelivery
{"deliveries":2,"businessEffects":1,"processedMarkers":1,"sameJobId":true,"duplicateResultInserted":false,"inflightAfterAck":0}
  1. Duplicate kontrolü aynı job’ın effect’ini ikinci kez uygulamaz.
  2. İki delivery mutlaka iki business effect oluşturur.
Gerekçeli cevabı oku

Duplicate kontrolü aynı job’ın effect’ini ikinci kez uygulamaz. — sameJobId=true ve processedMarkers=1, bu örneğin business idempotency kapsamını gösterir. Bu sonuç transport için exactly-once garantisi değildir.

Outbox relay publish etti, fakat sent marker yazılmadı. Retry neden duplicate publish oluşturabilir? Outbox hangi işlemleri atomic tutar?

Gerekçeli cevabı oku

Database transaction’ı note version ile pending outbox row’unu birlikte commit veya rollback eder. Relay’in publish etmesi ve sent marker yazması bu yerel transaction’ın dışındadır. Publish sonrasında marker yazılamazsa retry aynı kaydı yeniden publish edebilir. Consumer idempotency ayrıca gerekir. Örnek external effect’leri SQL transaction’ına dahil etmez ve gerçek broker çalıştırmaz.

□ Outbox’ın yerel atomicity kapsamını end-to-end exactly-once’dan ayırdım.

□ Publish ile sent marker arasındaki boşluğun duplicate doğurabileceğini açıkladım.

Uygulama konsolunu aç · request / response / browser
Request, URL, cookie ve DOM örneklerini ayrıca aç

Kaynaklar ve kapsam