Sayımı çevrimdışı yapmak: mobil terminal mimarisi
Sayım gecesi altı terminal, üç kişi ve on dört bin satır. Saat 23.40'ta depo koridorunda kablosuz ağ düşüyor ve iki terminalde son yirmi dakikanın okumaları kayboluyor. Bu senaryo saha uygulamalarında istisna değil, varsayılan durumdur. Çevrimdışı çalışma sonradan eklenen bir özellik olarak tasarlandığında bu şekilde biter. Baştan mimari kabul olarak alındığında ise sayım ağ olmadan da tamamlanır.
Depoda ağ neden yoktur
Sorun genellikle altyapı bütçesi değildir. Depo ortamı radyo dalgaları için düşman bir ortamdır. Metal raf sistemleri sinyali yansıtır ve söndürür. Soğuk hava deposunun yalıtımı kalın metal panellerden oluşur. Bodrum katındaki stok alanına erişim noktası çekmez. Yüksek raflı bir depoda erişim noktaları tavana asılıdır ve alt raflarda çalışan terminal gölgede kalır.
İkinci kaynak hareketliliktir. Sayım yapan kişi sabit durmaz; koridor boyunca yürür ve erişim noktaları arasında sürekli devreder. Devir anında bağlantı bir iki saniye kopar. Her okumada sunucuya yazmaya çalışan bir uygulama bu iki saniyede veri kaybeder ya da kullanıcıyı bekletir.
Üçüncü kaynak zamanlamadır. Sayım genellikle mesai dışında, gece ya da hafta sonu yapılır. Ağ ekibi yoktur, sorun çıktığında müdahale eden kimse yoktur ve sayımın ertelenme maliyeti yüksektir.
Bu üç nedenin ortak sonucu şudur: uygulama, ağın olmadığını varsayarak tasarlanmalı, ağ geldiğinde ise onu fırsat olarak kullanmalıdır.
Çevrimdışı çalışmanın gerçek sözleşmesi
Çevrimdışı çalışıyor ifadesi çoğu üründe veriyi bellekte tutmak anlamına gelir. Uygulama kapanınca ya da cihaz yeniden başlayınca veri gider. Gerçek sözleşme daha katıdır.
Kullanıcı barkodu okuduğunda uygulama, veriyi cihazın kalıcı deposuna yazar ve yazma tamamlanmadan kullanıcıya onay göstermez. Bu yazma işleminin yirmi milisaniyenin altında tamamlanması gerekir; aksi halde okuma hızı düşer ve kullanıcı uygulamayı beklemeye başlar. Kullanıcı beklerse sayım disiplinini bozar ve okumadan geçer.
Onay geri bildirimi görsel olmakla kalmamalıdır. Sayım yapan kişi ekrana bakmaz, rafa bakar. Kısa titreşim ve sesli geri bildirim, okumanın kaydedildiğini bildirmenin tek güvenilir yoludur.
Ağ geldiğinde uygulama arka planda senkron başlatır. Senkron kullanıcıyı kesmez, ekranı kilitlemez ve başarısız olduğunda sessizce yeniden dener. Kullanıcının gördüğü tek şey, gönderilmeyi bekleyen satır sayısıdır.
Cihazdaki veri modeli
Cihaz tarafında gömülü bir SQLite veritabanı yeterlidir ve tercih edilmelidir. Sunucu şemasının küçültülmüş bir kopyası değil, sayıma özgü sade bir şema kurulur.
Sayım oturumu tablosu sayımın kimliğini, şubesini, tipini, başlangıç zamanını ve durumunu tutar. Sayım satırı tablosu her okuma için bir satır yazar. Burada kritik karar şudur: satırlar toplanabilir yazılır, güncellenmez. Aynı barkod on kez okunduğunda tek satır güncellenmez, on satır yazılır.
Bu karar iki sorunu birden çözer. Birincisi, eş zamanlı yazma çakışması ortadan kalkar. İkincisi, denetim izi doğal olarak oluşur; hangi kullanıcının hangi saniyede ne okuduğu görülebilir. Yanlış okuma silinmez, ters işaretli bir düzeltme satırı yazılır.
Her satır cihazda üretilen bir tekil kimlik taşır. Bu kimlik sunucuda üretilmez, çünkü sunucuya ulaşmadan önce satırın kimliği olmak zorundadır. Yanına cihaz kimliği ve cihazın kendi artan sayacı eklenir. Sayaç sıralamayı, tekil kimlik ise idempotanlığı sağlar.
Cihaz saati güvenilmezdir. Kullanıcı saati değiştirebilir, cihaz yeniden başladığında saat kayabilir. Bu yüzden hem cihaz saati hem de senkron sırasında sunucunun atadığı zaman damgası saklanır ve raporlarda sunucu zamanı kullanılır.
- SayimOturum — oturum kimligi, sube, tip, durum
- SayimSatir — satir kimligi (uuid), cihaz kimligi, cihaz sayaci, barkod, miktar, cihaz zamani
- SenkronKuyruk — gonderilmemis satirlarin listesi ve deneme sayisi
- Referans — barkod ve urun eslesmesi icin yerel kopya
Idempotent senkron
Senkronun tek ve en önemli özelliği, aynı paketin iki kez gönderilmesinin sonucu değiştirmemesidir. Ağın kopması, cevabın kaybolması ve isteğin yeniden denenmesi olağan durumdur; bu durumlarda satır iki kez yazılmamalıdır.
Bunu sağlayan mekanizma basittir. Satır kimliği istemcide üretilir ve sunucu tarafında bu kimlik üzerinde tekil indeks bulunur. Yazma işlemi, kimlik zaten varsa hiçbir şey yapmaz. Sunucu her durumda başarı döner ve kabul edilen kimlik listesini yanıta koyar. İstemci bu listeyi alınca kuyruktan siler.
Paketleme boyutu deneyle belirlenir. Beş yüz satırlık paketler zayıf bağlantıda iyi çalışır; daha büyük paketler zaman aşımına düşer ve tamamı yeniden gönderilir. Paket başına tek bir işlem açılır, böylece kısmen yazılmış paket kalmaz.
Yeniden deneme aralığı üstel olarak artmalı ve bir üst sınıra oturmalıdır. Altı terminal aynı anda ağ bulduğunda hepsinin aynı saniyede tam paketle saldırması sunucuyu gereksiz yorar; rastgele bir dağıtım eklenmesi bu yığılmayı önler.
Uygulama katmanı bu noktada ince kalır. Node.js tarafındaki servis satırları doğrular, oturumun açık olduğunu kontrol eder, yetkiyi uygular ve toplu yazma yordamını çağırır. İş mantığı burada değil, saklı yordamdadır.
Sayım kapanışı ve fark yordamı
Sayım kapatılmadan önce iki koşul sağlanmalıdır: tüm terminallerin kuyruğu boş olmalı ve oturum sunucu tarafında kapanışa uygun durumda bulunmalıdır. Kapanış işlemi bir kişinin butona basmasıyla değil, sistemin bu iki koşulu doğrulamasıyla gerçekleşir.
Kapanışta saklı yordam çalışır ve okunan miktarları ürün bazında toplar, sistem stoğuyla karşılaştırır ve fark satırlarını üretir. Kritik ayrıntı, karşılaştırmanın hangi ana ait stokla yapılacağıdır. Sayım devam ederken satış ve mal kabul devam ediyorsa, sayım başlangıç anındaki stok fotoğrafı alınır ve sayım süresince oluşan hareketler ayrı olarak eklenir.
Fark satırları doğrudan stoğa yazılmaz. Önce onaya düşer. Belirli bir tutarın veya belirli bir yüzdenin üstündeki farklar ikinci bir onay ister. Onaylanan farklar sayım düzeltme hareketi olarak yazılır ve maliyeti tanımlı bir kalem üzerinden işlenir.
On dört bin satırlık bir sayımda tipik olarak yüzlerce fark satırı çıkar. Bu listenin ham haliyle kimseye faydası yoktur. Farkları tutara göre sıralamak, tekrar eden ürünleri gruplamak ve olası nedenleri işaretlemek listeyi kullanılabilir hale getirir.
Ne yapmalı
Sayım uygulamasını ağ yokken test edin, ağ varken değil. Uçuş moduna alın, sayımı bitirin, cihazı yeniden başlatın ve sonra ağı açın. Veri kaybı varsa mimari eksiktir.
Satırları güncellemeyin, ekleyin. Düzeltmeyi ters kayıtla yapın. Bu kural hem çakışmayı hem denetim izi ihtiyacını tek hamlede çözer.
Satır kimliğini istemcide üretin ve sunucuda tekil indeksle koruyun. Idempotanlık olmadan yeniden deneme mekanizması kurulamaz.
Sunucu zamanını yetkili kabul edin, cihaz zamanını yalnızca sıralama ipucu olarak saklayın.
Mindpera'nın saha uygulaması Capacitor üzerinde çalışır ve bu sözleşmeyi uygular: cihazda kalıcı yerel depo, toplanabilir satır yazımı, idempotent senkron ve kapanışta saklı yordamla üretilen fark listesi. Mind Stock modülü farkları onay akışına bağlar, düzeltme hareketleri maliyet tarafına aynı yordam üzerinden yansır.