Mühendislik//8 dk okuma

Translation Sync Engine'in İçinde: Lokalizasyon için Güvenilir Bir Async Pipeline Nasıl İnşa Ettik

Eray Gündoğmuş
Paylaş

Çeviri yönetimi, üç sistemi senkronize tutmaya çalışana kadar basit görünür: geliştiricilerin kod yazdığı bir Git deposu, çevirmenlerin çalıştığı bir veritabanı ve uygulamanızın çalışma zamanında çevirileri çektiği bir CDN. Bir sistemde bir key değiştiğinizde, diğer ikisinin de bundan haberdar olması gerekir — güvenilir biçimde, hızlıca ve veri kaybı olmadan.

Bu, sync engine'i inşa etmek için çözdüğümüz problem. Bu yazıda mimariyi, mesaj tiplerini, çakışma algılama sistemini ve tüm bunları çalışır hale getiren güvenilirlik garantilerini ele alacağız.


Senkron Çeviri İş Akışlarının Sorunu

Better i18n'in erken geliştirme aşamasında, çeviri senkronizasyonları senkrondu. Bir geliştirici kod push'ladığında, webhook handler'ımız değişiklikleri satır içinde işler, veritabanını günceller, CDN dosyalarını yeniden oluşturur ve bir yanıt döndürürdü. İşe yarıyordu — ta ki yaramaz hale gelene kadar.

Hata modları öngörülebilirdi:

  • Zaman aşımları. 5.000 key'e sahip bir depoyu diff'lemek zaman alır. GitHub webhook'larının 10 saniyelik bir zaman aşımı vardır. Büyük projelerde senkronizasyonlar sessizce başarısız olurdu.
  • Kısmi güncellemeler. Veritabanı güncellendikten sonra CDN yüklemesi başarısız olursa, çeviriler senkronizasyondan çıkardı. Birisi manuel olarak yeniden senkronizasyon tetikleyene kadar kullanıcılar eski içeriği görürdü.
  • Görünürlük eksikliği. Bir senkronizasyon başarısız olduğunda, ne olduğuna dair hiçbir kayıt yoktu. Hata ayıklama, sunucu günlüklerini okumayı ve zaman damgalarını ilişkilendirmeyi gerektiriyordu.

Tetikleyiciyi işten ayıran, otomatik yeniden deneme sağlayan ve her operasyona tam görünürlük sunan bir mimariye ihtiyacımız vardı.


Cloudflare Queues ile Tanışın

Sync engine'in omurgası olarak Cloudflare Queues'u seçtik. Queues, tam olarak ihtiyacımız olan şeyi sunar: dayanıklı, sıralı mesaj teslimi ve en-az-bir-kez semantiği.

Mimari açıktır:

GitHub Webhook → API Handler → Queue (mesajı kuyruğa ekle) → Worker (mesajı işle)
                                                                      ↓
                                                     Activity Log + Database + CDN

API handler minimum iş yapar: webhook'u doğrular, bir REPO_PUSH_SYNC mesajı kuyruğa ekler ve 200 döndürür. Asıl işlem, mesajları alıp yürüten bir Cloudflare Worker olan kuyruk tüketicisinde eş zamansız olarak gerçekleşir.

Bu ayrımın üç anlık faydası vardır:

  1. Webhook yanıtları hızlıdır. Büyük depolar için bile artık zaman aşımı yoktur.
  2. Hatalar otomatik olarak yeniden denenir. Worker çökerse veya bir API çağrısı başarısız olursa, mesaj üstel geri çekilme ile yeniden iletilir.
  3. Operasyonlar gözlemlenebilirdir. Her mesaj yapılandırılmış bir activity log üretir.

10 Mesaj Tipi, Tek Tüketici

Sync engine, her birinin kendi handler'ına sahip 10 farklı mesaj tipini işler:

Senkronizasyon operasyonları:

  • SYNC_START — Tam veya artımlı GitHub senkronizasyonu. Dosyaları getirir, key'leri karşılaştırır, veritabanını günceller ve isteğe bağlı olarak yeni çevirilerle bir pull request oluşturur.
  • REPO_PUSH_SYNC — Push webhook olayları için optimize edilmiş yol. Yalnızca push'ta değişen dosyaları işler; artımlı senkronizasyonları neredeyse anlık hale getirir.

CDN operasyonları:

  • CDN_SETUP — Bir proje CDN'ini bağladığında ilk manifest ve boş dil dosyalarını oluşturur.
  • CDN_UPLOAD — R2 depolama alanına tek bir JSON çeviri dosyası yazar.
  • CDN_MERGE — Yeni çevirileri mevcut bir CDN dosyasıyla birleştirir. Bu, kısmi yayınlar için kritiktir — değişmeyenleri kaldırmadan yeni çeviriler eklemek istersiniz.
  • CDN_CLEANUP — Bir proje için tüm R2 dosyalarını siler. Proje silinirken veya kullanıcı sıfırdan başlamak istediğinde kullanılır.

AI operasyonları:

  • AI_CONTEXT_ANALYSIS — Projenin web sitesini taramak için Firecrawl kullanır, ardından içeriği bir çeviri bağlam modeli oluşturmak için Gemini'ye besler. Bu bağlam, makine çevirisinin sektöre özgü terminolojiyi anlamasına yardımcı olur.
  • REPO_ANALYSIS — Framework'ü tespit etmek (React, Next.js, Flutter vb.), mevcut çevirileri çıkarmak ve bir terminoloji sözlüğü oluşturmak için GitHub deposunu tarar.

Yayınlama:

  • PUBLISH_BATCH — Çeviri iş akışındaki son adım. Onaylanan çevirileri alır ve hem CDN'e (anında erişilebilirlik için) hem de GitHub'a (sürüm kontrolü için) gönderir. Bu atomik bir operasyondur — iki yazma işleminden biri başarısız olursa, tüm yayın yeniden denenir.

Sözlük:

  • GLOSSARY_SYNC — Terminoloji sözlüklerini DeepL ile senkronize eder. "workspace" kelimesinin Fransızcada her zaman "espace de travail" olarak çevrilmesi gerektiğini tanımladığınızda, bu mesaj DeepL'in sözlüğünün güncellenmesini sağlar; böylece gelecekteki tüm makine çevirileri tutarlı olur.

Her mesaj tipi izole edilmiştir. CDN_UPLOAD'daki bir hata SYNC_START'ı engellemez. Yavaş bir AI_CONTEXT_ANALYSIS, PUBLISH_BATCH'i geciktirmez. Bu izolasyon, engine'in güvenilirliğinin anahtarıdır.


Job Sistemi

Mesajlar alt düzeydir. Job'lar ise kullanıcıların ve sistemin etkileşime girdiği üst düzey iş akışlarıdır. Sync engine 12 job tipini destekler:

Job TipiTetikleyiciÜretilen Mesajlar
initial_importProje kurulumuSYNC_START, CDN_SETUP
incremental_syncPush webhookREPO_PUSH_SYNC, CDN_MERGE
full_syncManuel tetiklemeSYNC_START, CDN_UPLOAD (dil başına)
source_syncKaynak dil değişikliğiSYNC_START
bulk_translateToplu çeviri isteğiBirden fazla CDN_UPLOAD
publishTek dil yayınıPUBLISH_BATCH, CDN_UPLOAD
batch_publishÇok dilli yayınBirden fazla PUBLISH_BATCH
cdn_uploadDoğrudan CDN yazmaCDN_UPLOAD
cdn_mergeKısmi CDN güncellemesiCDN_MERGE
cdn_setupCDN başlatmaCDN_SETUP
cdn_cleanupProje temizlemeCDN_CLEANUP
glossary_syncSözlük güncellemeGLOSSARY_SYNC

Tek bir job birden fazla mesaj üretebilir. Örneğin, 8 dilli bir projede full_sync job'ı 1 SYNC_START mesajı ve ardından 8 CDN_UPLOAD mesajı üretir — her dil dosyası için bir tane. Job, tüm mesajlarındaki toplam durumu izler.


45+ Activity Action: Yapılandırılmış Gözlemlenebilirlik

Her mesaj handler'ı ilerledikçe yapılandırılmış activity action'lar kaydeder. Bunlar serbest metin log satırları değildir — hem hata ayıklama deneyimini hem de gerçek zamanlı kullanıcı arayüzünü besleyen tiplendirilmiş, yapılandırılmış olaylardır.

Tipik bir SYNC_START akışı bu activity trail'i üretir:

SYNC_STARTED
  → FETCH_FILES (GitHub'dan çeviri dosyaları getiriliyor)
  → FILES_FETCHED (12 dosya bulundu)
  → COMPARE_KEYS (veritabanıyla diff alınıyor)
  → KEYS_ADDED (47 yeni key)
  → KEYS_REMOVED (3 kullanımdan kalkmış key)
  → KEYS_UPDATED (12 değiştirilmiş değer)
  → UPDATE_DATABASE (değişiklikler kalıcı hale getiriliyor)
  → PR_GENERATION_STARTED (çeviri PR'ı oluşturuluyor)
  → PR_CREATED (PR #142 açıldı)
  → SYNC_COMPLETED (süre: 3.2s)

45'ten fazla farklı action tipiyle her operasyona ayrıntılı görünürlük elde edersiniz. Bir şey başarısız olduğunda, son kaydedilen action size pipeline'ın tam olarak nerede durduğunu ve hangi verinin zaten işlendiğini söyler.

Bu activity action'lar aynı zamanda senkronizasyon geçmişi kullanıcı arayüzünü de besler. Ekibiniz, sunucu günlüklerine dokunmadan çalışmış her senkronizasyonu, ne yaptığını, ne kadar sürdüğünü ve başarılı olup olmadığını görebilir.


Çakışma Algılama ve Çözümleme

Çakışmalar, herhangi bir senkronizasyon sistemindeki en zor problemdir. İki kişi aynı çeviri key'ini düzenler — biri kod tabanında, biri çeviri kullanıcı arayüzünde. Kim kazanır?

Cevabımız: kimse otomatik olarak kazanmaz. Sync engine çakışmaları algılar ve insan çözümlemesi için yüzeye çıkarır.

Algılama

COMPARE_KEYS sırasında engine, gelen her key'i veritabanına karşı kontrol eder. Bir key hem depoda hem de veritabanında son başarılı senkronizasyondan bu yana değiştirilmişse, çakışma olarak işaretlenir. Engine, her iki değeri de değiştirilme zaman damgalarıyla birlikte saklar.

Çözümleme

Çakışmalar, tam bağlamıyla birlikte dashboard'da görünür:

  • Kaynak değer (depodan)
  • Veritabanı değeri (çeviri kullanıcı arayüzünden)
  • Son senkronize edilmiş değer (ortak ata)
  • Her değişiklik için zaman damgaları

Kullanıcılar çakışmaları tek tek veya toplu olarak, kaynak değeri korumayı, veritabanı değerini korumayı veya manuel birleştirme yazmayı seçerek çözebilir. Her çözümleme bir activity action olarak kaydedilir.

Bu yaklaşım, çeviri iş akışlarındaki en yaygın veri kaybı senaryosunu önler: bir geliştiricinin kod push'unun, bir çevirmenin özenle incelediği çalışmasını sessizce üzerine yazması.


Güvenilirlik Garantileri

Sync engine dört güvenilirlik ilkesi etrafında tasarlanmıştır:

En-az-bir-kez teslim. Cloudflare Queues, her mesajın en az bir kez teslim edilmesini garanti eder. Mesajlar worker yeniden başlatmalarını, deployment'ları ve altyapı arızalarını atlatır.

Idempotent handler'lar. Mesajlar birden fazla kez teslim edilebildiğinden, her handler idempotent'tir. Aynı içerikle bir CDN_UPLOAD'ı yeniden işlemek aynı sonucu üretir. Bir SYNC_START'ı yeniden işlemek, mevcut veritabanı durumuyla karşılaştırır; dolayısıyla yinelenen senkronizasyonlar etkin biçimde no-op'tur.

Sıralı işleme. Aynı proje için mesajlar sırayla işlenir. CDN_MERGE, her zaman onu üreten SYNC_START'tan sonra çalışır. Bu, bir CDN dosyasının veritabanı yeni key'leri yansıtmadan önce güncelleneceği yarış koşullarını önler.

Geri çekilme ile otomatik yeniden deneme. Başarısız mesajlar üstel geri çekilme ile yeniden denenir. Geçici hatalar — API hız sınırları, ağ kesintileri, geçici R2 kullanılamazlığı — insan müdahalesi olmadan kendiliğinden çözülür. Kalıcı hatalar (geçersiz veri, eksik izinler) kaydedilir ve dashboard'da yüzeye çıkarılır.


Bu Ekibiniz İçin Ne Anlama Geliyor?

Sync engine arka planda çalışır. GitHub deponuzu bağlarsınız ve senkronizasyonlar kendiliğinden çalışır. Kod push'layın, çevirileriniz saniyeler içinde güncellensin. Çevirileri onaylayın, atomik olarak CDN'inize yayınlanıp deponuza commit edilsin.

Bir şeyler ters gittiğinde — ve dağıtık sistemlerde bir şeyler her zaman ters gider — engine yeniden dener, kaydeder ve sorunu yüzeye çıkarır. Sessiz başarısızlık yok. Tutarsız durum yok. Kayıp çeviri yok.

Doğru yapılmış async processing'in vaat ettiği budur: ekibiniz çevirilere odaklanır, altyapı gerisini halleder.

Comments

Loading comments...