Offline Queue este un mecanism care salvează operațiile utilizatorului local când dispozitivul este offline și le trimite pe server după restabilirea conexiunii. Fără coada offline, utilizatorul pierde toate acțiunile efectuate fără internet, ceea ce în aplicațiile mobile este inacceptabil. Potrivit Google Developers (2025), implementarea arhitecturii offline-first crește retenția utilizatorilor cu 30% în regiunile cu internet instabil.
Principalele puncte
Offline Queue este o colecție ordonată de operații (creare, actualizare, ștergere) pe care aplicația le salvează local când dispozitivul nu are acces la rețea. De îndată ce conexiunea este restabilită, coada trimite operațiile pe server în aceeași ordine în care utilizatorul le-a efectuat.
Imaginați-vă un scenariu: utilizatorul unui messenger tastează mesaje în metrou fără internet. Fiecare apăsare a butonului „Trimite” este adăugată în Offline Queue. Când trenul iese din tunel și rețeaua apare, toate mesajele sunt trimise automat. Experiența utilizatorului este fluentă: nu observă că a fost offline, în afară de o ușoară întârziere la trimitere.
Potrivit Uber Engineering (2024), coada lor offline procesează peste 2 milioane de operații pe zi în regiuni cu calitate scăzută a conexiunii. Coada utilizează stocarea locală Room cu ordine FIFO și un mecanism de livrare garantată exactly-once.
data class QueuedOperation(
val id: String,
val type: OperationType,
val endpoint: String,
val payload: String,
val timestamp: Long,
val retryCount: Int = 0,
val idempotencyKey: String
)
Fiecare operație conține toate datele necesare pentru retrimitere: endpoint, corpul cererii, marcaj temporal și idempotencyKey. Baza de date Room garantează păstrarea cozii la repornirea aplicației și la defecțiunile sistemului de operare.
Garantarea livrării este sarcina principală a cozii. Utilizatorul trebuie să fie sigur că acțiunea sa (trimiterea unui mesaj, like, comandă) va fi executată, chiar dacă rețeaua este indisponibilă la momentul executării. Offline Queue cu mecanism de retry asigură livrarea eventuală (eventually).
Îmbunătățirea UX în condiții de conexiune slabă — potrivit GSMA Mobile Economy Report (2025), aproximativ 40% dintre utilizatorii mobili din lume au o conexiune instabilă la internet. Offline Queue face aplicația utilizabilă în metrou, lifturi, zone îndepărtate — oriunde conexiunea este intermitentă.
Reducerea pierderii de date — fără coadă, toate acțiunile efectuate offline se pierd. Utilizatorul poate completa un formular lung, apăsa „Trimite” și vedea o eroare de rețean — toate datele introduse dispar. Offline Queue salvează datele și le trimite la prima ocazie. Salvarea automată în Google Docs este un exemplu clasic de coadă offline pentru documente.
Sincronizarea asincronă — coada permite aplicației să nu blocheze interfața pe durata trimiterii. Utilizatorul continuă să lucreze, iar managerul de sincronizare procesează coada în fundal. Aceasta este conformă cu principiile Arhitecturii Reactive și îmbunătățește receptivitatea interfeței.
Trei straturi ale cozii: stocare (persistence), dispecer (scheduler) și procesor (executor). Stocare — Room cu tabelul QueuedOperation. Dispecer — WorkManager (Android) sau BGTaskScheduler (iOS), care pornește sincronizarea la apariția rețelei. Procesor — un iterator secvențial FIFO care trimite operațiile una câte una.
Ordinea de procesare este critică pentru consistența datelor. Dacă utilizatorul a creat o înregistrare și apoi a editat-o, ambele operații trebuie trimise în aceeași ordine. În caz contrar, serverul va primi mai întâi actualizarea unei înregistrări inexistente — eroare. Sequential FIFO — ordine strictă cu controlul dependențelor între operații.
Strategia de îmbinare — dacă în coadă există CREATE și imediat după DELETE al aceluiași obiect, ambele operații pot fi șterse fără trimitere: starea finală — obiectul nu a fost creat. Similar, CREATE + UPDATE CREATE poate fi îmbinat într-un singur CREATE cu cele mai recente date. Optimizarea cozii reduce numărul de cereri HTTP și accelerează sincronizarea.
Potrivit Android Developers (2025), WorkManager este metoda preferată pentru procesarea Offline Queue pe Android: garantează execuția chiar și după repornirea dispozitivului, suportă constrângeri privind disponibilitatea rețelei și permite stabilirea unei politici de reîncercare prin NetworkType.CONNECTED.
class SyncWorker(
private val context: Context,
private val params: WorkerParameters
) : CoroutineWorker(context, params) {
override suspend fun doWork(): Result = runCatching {
queueRepository.processNextBatch(batchSize = 10)
Result.success()
}.getOrDefault(Result.retry())
}
CoroutineWorker procesează loturile de operații și returnează Result.retry() la eșec — WorkManager reia automat execuția cu o întârziere exponențială. Aceasta este cea mai simplă modalitate de a obține o Offline Queue fiabilă pe Android.
Exponential Backoff — strategia standard de reîncercare cu interval crescător: 2 sec, 4 sec, 8 sec, 16 sec și așa mai departe până la un prag maxim. Aceasta previne supraîncărcarea repetată a serverului dacă acesta este temporar indisponibil. Biblioteca Java Resilience4j (2024) oferă o implementare gata preparată Retry cu backoff configurabil.
Numărul maxim de încercări — un parametru critic. Dacă după 5–10 încercări operația nu a reușit, încercările ulterioare sunt inutile. Se recomandă dead letter queue: după epuizarea încercărilor, operația este mutată într-un tabel separat pentru analiză manuală. Potrivit Microsoft Patterns & Practices (2024), dead letter queue simplifică depanarea problemelor de sincronizare și previne blocarea cozii de către operații eronate.
Jitter — variație aleatoare — adăugarea unui număr aleator la intervalul backoff. Dacă o mie de dispozitive și-au restabilit simultan conexiunea după o deconectare, toate vor începe sincronizarea în același timp. Jitter le distribuie în timp, prevenind Cache Stampede pe server. Jitter complet: delay = random(0, backoff) — recomandat de AWS (2024) pentru clienții API.
Last Write Wins (LWW) — cea mai simplă strategie: la conflict, câștigă operația cu marcajul temporal mai recent. LWW necesită sincronizarea timpului — timestamp trebuie generat pe server sau să utilizeze Logical Clock (ceasuri Lamport). Dezavantaj: datele unui utilizator pot fi suprascrise de datele altuia fără avertisment.
OT (Operational Transformation) — algoritm utilizat de Google Docs și Figma pentru editare colaborativă în timp real, inclusiv în modul offline. OT transformă operațiile astfel încât să se aplice oricărei stări a documentului, asigurând consistența fără blocaje. CRDT (Conflict-Free Replicated Data Types) — alternativă la OT, care câștigă popularitate în aplicațiile mobile: datele sunt structurate astfel încât conflictele să fie rezolvabile matematic, fără un server central.
Îmbinare personalizată — pentru aplicații cu un model simplu de date (note, contacte) se pot implementa reguli personalizate de îmbinare. De exemplu, pentru o notă: dacă textul a fost modificat în două versiuni, împreună-le ca o concatenare cu un separator. Conflict rezolvat de utilizator — dacă îmbinarea automată nu este posibilă, afișați utilizatorului ambele versiuni și propuneți alegerea. Dropbox (2024) utilizează această abordare pentru conflictele în fișiere offline, creând copii cu prefixul „Conflicted Copy”.
Idempotency Key — un identificator unic al operației pe care serverul îl utilizează pentru detectarea cererilor duplicate. Dacă clientul trimite aceeași cerere cu aceeași cheie, serverul returnează rezultatul operației deja executate, fără a o executa din nou. Acest lucru este critic pentru Offline Queue, unde retrimiterile sunt posibile în cazul erorilor de rețean.
Formatul idempotency key — UUID sau hash al parametrilor cererii. Serverul trebuie să stocheze cheile executate împreună cu rezultatul pentru o perioadă de timp (de obicei 24 de ore) pentru detectarea duplicatelor. Stripe API (2024) — un exemplu de referință: cheia este transmisă în antetul Idempotency-Key, iar cererile repetate cu aceeași cheie returnează răspunsul stocat în cache.
Generarea pe partea clientului — cheia este creată pe client înainte de trimiterea operației și salvată în tabelul QueuedOperation. La reîncercare, cheia nu se schimbă. Arhitectura exactly-once — combinația dintre idempotency key pe client și deduplicarea pe server — singura modalitate de a garanta că operația nu va fi executată de două ori.
fun createOperation(type: OperationType, payload: String): QueuedOperation =
QueuedOperation(
id = UUID.randomUUID().toString(),
type = type,
endpoint = type.endpoint,
payload = payload,
timestamp = currentTimeMillis(),
idempotencyKey = UUID.randomUUID().toString()
)
Fiecare operație primește două UUID-uri: unul — identificatorul înregistrării în coadă, al doilea — idempotency key pentru server. Deduplicarea pe partea serverului după idempotencyKey garantează că, chiar și la retrimitere, comanda nu va fi duplicată.
Întrebări frecvente
Cache-ul stochează copii ale datelor pentru citire rapidă offline. Offline Queue stochează operațiile utilizatorului pentru scrierea ulterioară pe server. Cache-ul funcționează pentru citire, coada — pentru scriere. Ambele componente pot coexista într-o arhitectură offline-first.
Limita recomandată — 100–500 de operații. Mai mult — risc de depășire a memoriei și sincronizare lungă la restabilirea rețelei. La depășirea limitei, aplicația trebuie să avertizeze utilizatorul și să propună prioritizarea operațiilor. Limită rezonabilă — 50 de operații de actualizare + 10 de creare.
Operațiile mai vechi de 7 zile cu succes zero sunt mutate în dead letter queue. Analizați-le manual: poate că API-ul s-a schimbat și endpoint-ul nu mai există. Curățarea automată — o sarcină HealthCheck o dată pe zi șterge sau arhivează operațiile expirate.
Utilizați un graf de dependențe (DAG): fiecare operație conține o listă de parentOperationId care trebuie finalizate înainte de trimiterea ei. Interogarea Room cu ORDER BY parent va returna operațiile în ordinea corectă. Trimitere în cascadă — după finalizarea fiecărei operații, verificați dacă operațiile copil au fost deblocate.
Utilizați Network Less Tool în Android Emulator sau Network Link Conditioner în iOS Simulator pentru a emula pierderea rețelei. Scrieți teste care adaugă operații în coadă în modul offline, restaurează conexiunea și verifică dacă toate operațiile au fost trimise și procesate de server.
Concluzii
Vom dezvolta o aplicație mobilă la cheie
IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.
Citiți și