Günümüzde indie geliştiriciler için en değerli kaynaklardan biri zaman. Sürekli yeni projeler üretmek, kodlamak ve ardından bunları paylaşmak yoğun bir tempoyu gerektiriyor. SlothPost, bu dengeyi kurmak için geliştirilmiş bir araç olarak öne çıkıyor. Projelerinizin GitHub, Vercel ve App Store aktivitelerini izleyerek otomatik sosyal medya gönderileri oluşturuyor ve sizin onayınıza sunuyor. Peki, bu sistemin kalbinde yatan planlayıcı nasıl çalışıyor ve hangi veritabanı tasarımı sırlarını barındırıyor?
Zaman Yönetiminde Devrim: Cron’dan Ötesi
SlothPost’un en kritik bileşeni, her dakika çalışan ve "hangi gönderiler şu anda yayınlanmalı?" sorusunu yanıtlayan bir planlayıcı sistem. Bu sistem, kullanıcıların ürünleri için ayarladıkları yayın takvimlerine dayanıyor. Örneğin, bir kullanıcı pazartesi ve perşembe sabah 9’da X’e, pazartesi günleri Threads’e otomatik gönderi planlayabilir. Ancak bu basit görünen senaryo, ölçeklendirildiğinde ciddi performans sorunlarına yol açıyor.
Geleneksel yaklaşımda, tüm ürün kayıtlarını tarayıp aktif olanları filtrelemek ve yayın zamanını kontrol etmek mümkün. Ancak kullanıcı sayısı 10 bindiğinde bu yöntem felakete dönüşüyor. Her dakika çalışan bir cron işi, milyonlarca kaydı tarayarak veritabanını yoruyor ve yanıt süreleri felaket boyutlara ulaşıyor. İşte tam da bu noktada, Amazon DynamoDB’nin Global Secondary Index (GSI) özelliği devreye giriyor.
Sparse GSI: Veritabanı Performansında Devrim
DynamoDB’nin en güçlü özelliklerinden biri olan GSI’ler, sadece belirli bir niteliği taşıyan öğeleri indeksliyor. Bu özellik, "sparse index" olarak adlandırılıyor ve planlayıcı sisteminde devrim yaratmaya yetiyor. SlothPost’ta her ürün için scheduleStatus ve nextRunAt adında iki yeni alan kullanıldı:
scheduleStatus: Ürünün aktif bir yayın planı olup olmadığını belirten bir nitelik. Aktifse değeriactive, değilse bu nitelik kayda bile eklenmiyor.nextRunAt: Ürünün bir sonraki yayın için planlandığı Unix zaman damgası. Her yayın gerçekleştikten sonra kullanıcının takvim yapılandırmasına göre yeniden hesaplanıyor.
GSI, scheduleStatus (bölüm anahtarı) ve nextRunAt (sıralama anahtarı) üzerine kurulmuş durumda. Planlayıcı her dakika çalıştığında, sadece aktif planları sorgulayan ve zaman damgası geçmiş olanları getiren bir sorgu yapıyor:
dynamoDB.query({
TableName: 'slothpost-products',
IndexName: 'scheduleStatus-nextRunAt-index',
KeyConditionExpression: 'scheduleStatus = :active AND nextRunAt <= :now',
ExpressionAttributeValues: {
':active': 'active',
':now': Date.now()
}
});Bu yaklaşımın en büyük avantajı, indeksin yalnızca aktif planları içermesi ve gereksiz kayıtları tamamen dışlaması. Sonuç olarak veritabanı taramalarından kurtuluyor ve sorgular saniyenin binde biri gibi sürelerde yanıt veriyor. Ölçeklenebilirlik konusunda ciddi bir avantaj sağlayan bu tasarım, sistemin 10 bin kullanıcıya kadar problemsiz çalışmasını mümkün kılıyor.
Gizli Hata: Zamanın Yokluğu
Her başarılı sistemin arkasında uzun uğraşlar ve bazen de beklenmedik hatalar yatıyor. SlothPost’un planlayıcı sisteminde de başlangıçta fark edilmeyen bir hata vardı. computeNextRunAt fonksiyonu, kullanıcının haftalık planında yer alan günlerin etkin olup olmadığını kontrol etmek için daySchedule.enabled alanını kullanıyordu. Ancak bu alan hiçbir yerde tanımlanmamıştı!
Aslında SlothPost’ta etkinlik durumu, zamanın olup olmadığına göre belirleniyor. Bir gün için zaman ayarlanmışsa o gün etkin, zaman boşsa etkin değil. Bu mantık basitçe typeof daySchedule.time === 'string' şeklinde kontrol edilebiliyordu. İlk hata, fonksiyonun her çağrısında null döndürmesi ve nextRunAt alanının asla güncellenmemesiydi. Sonuçta indekste hiçbir kayıt yer almıyordu ve planlayıcı boş sonuçlarla çalışmaya devam ediyordu. Hatanın tespiti uzun sürdü çünkü cron işi teknik olarak çalışıyordu — sadece sonuç bulunamamasıyla karşılaşıyordu.
Vercel Webhook’larında Karşılaşılan Engeller
SlothPost, Vercel Marketplace entegrasyonu olarak çalışıyor. Kullanıcılar Vercel hesaplarını bağladığında, hangi projeleri izlemek istediklerini seçiyorlar ve bu proje kimliği vercelProjectId alanına kaydediliyor. Bir deployment gerçekleştiğinde, gelen webhook’un hangi kullanıcıya ait olduğunu bulmak gerekiyor.
Bu sorunun çözümü de yine sparse GSI yaklaşımıyla mümkün oldu. vercelProjectId üzerine kurulan bir GSI, sadece ilgili projeye bağlı ürünleri indeksliyor ve gereksiz taramaları ortadan kaldırıyor. Ancak burada da beklenmedik bir engelle karşılaşıldı: Vercel’in REST API’si aracılığıyla programatik olarak webhook oluşturmak imkansız. API, 403 hata kodu ile yanıt veriyor. Çözüm, Integration Console üzerinden global bir webhook yapılandırmak oldu. Bu detay, dokümantasyonda yer almadığı için uzun süren deneme yanılmalar sonucu keşfedildi.
Dersler ve İpuçları
Sparse GSI’ler, yalnızca aktif öğelerin indekslendiği durumlarda olağanüstü performans avantajları sunuyor. Bu yaklaşım, tam tablo taramalarından kaçınarak sorguları hızlandırıyor ve indeks boyutunu küçültüyor. SlothPost’un planlayıcı sistemi, bu tasarımın ölçeklenebilirlik ve performans açısından ne kadar güçlü olduğunu kanıtlıyor.
Bazı önemli ipuçları:
removeUndefinedValues: trueayarı, TypeScript projelerinde DynamoDB kullanırken zorunlu. Bu ayar tanımlanmamış alanları otomatik olarak kaldırarak yazma işlemlerini kolaylaştırıyor.- Webhook yapılandırmalarında API yerine konsol arayüzünü kullanmak, beklenmedik engellerden kaçınmanın en güvenilir yolu.
- Veritabanı tasarımlarında niteliklerin varlığına dikkat etmek ve boş değerlerle çalışmaya hazırlıklı olmak gerekiyor.
SlothPost, Next.js ve Vercel üzerinde çalışırken veritabanı olarak DynamoDB’yi tercih ediyor. Zamanlanmış görevler için Cloudflare Workers kullanarak gerçek zamanlı performans sağlıyor. Bu mimari, indie geliştiricilerin üretkenliklerini artırmak için nasıl optimize edilebileceğinin güzel bir örneği.
Gelecekte, bu yaklaşımın farklı senaryolarda nasıl uygulanabileceğini ve hangi yeni optimizasyonların mümkün olduğunu görmek heyecan verici olacak.
Yapay zeka özeti
Amazon DynamoDB’nin sparse Global Secondary Index özelliğini kullanarak gerçek zamanlı gönderi planlayıcısı nasıl kurulur? Ölçeklenebilir veritabanı tasarımı ve karşılaşılan tuzaklar hakkında detaylar.