Tips & Tricks: ottimizzare la sincronizzazione dei blob

by Giuseppe Lanzi on 17 novembre 2015

Riprendo la scrittura dei Tips & Tricks dopo una pausa relativamente lunga e per farlo ho deciso di affrontare un argomento per il quale sono stati in molti a sottolinearmi il loro interesse: ottimizzare la sincronizzazione dei blob.

Come sapete il framework di sincronizzazione di Instant Developer si basa sul trasporto dei dati tramite stringhe XML: sia le singole variazioni della sincronizzazione differenziale sia l’intero stato di ogni documento da copiare sul dispositivo in caso di sincronizzazione completa vengono salvate in XML e trasferite al device. Ed è qui che si può incontrare il limite del dispositivo che, effettuando il parse di una stringa XML relativamente grande, va in out of memory facendo chiudere l’app.

I conti sono semplici: sincronizzando 1000 entità ognuna con un blob di 200KB il server dovrà mandare al client 200 x 1000 KB = 200MB! Se si parla di un’unica stringa XML bastano numeri decisamente più piccoli per renderne difficile l’apertura. Molti di voi sanno che viene in nostro aiuto la sincronizzazione parziale, che permette di sincronizzare i documenti a colpi di gruppi meno numerosi, ma non è l’unica strada percorribile.

A me piacerebbe che l’app potesse:

  1. poter sincronizzare i documenti liberamente, evitando di inviare i blob al client;
  2. disporre di un modo semplice per scaricare i blob mancanti al momento del bisogno.

Qui potete trovare un progetto di esempio in cui viene sincronizzata la classe Landscape, che rappresenta un panorama con un nome e una foto, quest’ultima è rappresentata con un blob su database. Il risultato che volevo ottenere nel crearlo era quello di avere una sincronizzazione il più veloce possibile, ma allo stesso tempo ottenere l’immagine da mostrare all’utente al momento opportuno. Per ottenere il risultato ho:

  1. creato un dominio per indicare che i blob dell’applicazione esprimono il concetto MY_BLOB;
  2. usato l’evento onGetNamedPropertyValue per indicare al framework di non inviare i blob al client;
  3. usato il metodo SyncService.ResyncDocument() per ottenere i blob al momento giusto.

Infatti, durante la sincronizzazione, alle varie classi documentali viene notificato l’evento onGetNamedPropertyValue con DO_DONTSYNC come propertyName, per permettere all’utente di utilizzare il metodo Documento.DontSync() e impedire la sincronizzazione automatica di una specifica proprietà. Io ho scelto i blob.

Una volta fatto questo mi sono chiesto “quando voglio che l’utente riceva l’immagine?” e nel mio caso la risposta era “quando guarda il documento in dettaglio”. Così ho usato l’onChangeRow per lanciare una procedura globale che sfrutta il metodo ResyncDocument per scaricare al volo l’immagine dal server. Tutto questo solo se tutti i blob che usano il concetto MY_BLOB all’interno del documento sono nulli.

Fate questa prova e capirete subito il meccanismo:

  1. lanciate le due applicazioni contenute all’interno del progetto, che rappresentano il server di sincronizzazione e l’app mobile;
  2. usate il comando Sync Now per fare la prima sincronizzazione;
  3. aprite il debug e vedrete che il client ha ricevuto 659 Byte, poca roba;
  4. chiudete il debug;
  5. scegliete un panorama dall’elenco e riaprite il debug, vedrete che il client ha ricevuto tutto il documento, qualche centinanio di KByte.

L’effetto collaterale della mia soluzione è che così è necessario disporre di connessione a internet nel momento dell’apertura del dettaglio, ma per aggirarlo è sufficiente usare il mio stesso metodo in una procedura in background in una server session sul dispositivo.

Ma questo esercizio lo lascio a voi :)

Quale trucco ti interessa leggere nel prossimo articolo tecnico?

  •    Implementare una sincronizzazione multi dominio
  •    Un esempio pratico dell'uso delle WebAPI DO Foundation con le edizioni Cloud
  •    Altro (specificare nei commenti)

{ 4 comments… read them below or add one }

1 Enrico 25 novembre 2015 alle 20:10

Mi piacerebbe molto un T&T su come sincronizzare i documenti gemelli all’interno della stessa applicazione.
Per documenti gemelli intendo diverse istanze dello stesso record, presenti in videate o pannelli differenti, che risultano però completamente slegati tra di loro. Aggiornandone o cancellandone uno gli altri continuano a mantenere (e mostrare) il valore scorretto.

2 Giuseppe Lanzi 26 novembre 2015 alle 14:38

@Enrico ma per la sincronizzazione delle varie videate sullo stesso record non sarebbe meglio utilizzare sempre la stessa istanza di documento? Magari usando la addRef?

Mi interessera l’argomento, ma prima di scrivere un post mi piacerebbe capire meglio l’esigenza. Perché non apri un thread sul forum per questo (e magari segnali nel testo che deriva dal blog così i colleghi me lo assegnano? :) )

3 Enrico 26 novembre 2015 alle 15:13

Volentieri.
Posso anticiparti il tuo suggerimento coglie nel segno , addref fa esattamente quello che chiedo. ma che strategia usare per popolare tramite lui tutti i pannelli nei vari forms? magari senza rinunciare a tutti gli automatismi e agevolazioni che offrono i pannelli basati su DO?.
ti scrivo su forum (la mia login è theguru)

4 Enrico 26 novembre 2015 alle 17:55

Ok, fatto. Grazie come sempre della tua assistenza!

Leave a Comment

Previous post:

Next post: