Italian GET alcuni dati da database su server

Elric

Well-Known Member
Licensed User
Ciao a tutti!

Sto studiando CloudKVS.

L'esempio di Erel dà al Client la possibilità di scegliere un numero e un colore; questi vengono memorizzati in locale e inviati al server. Il server memorizza in un unico database ciò che gli viene inviato.

Nell'esempio il server riceve dal client ma non invia nulla al client (o almeno così mi sembra). Mi sono chiesto, quindi, come fare?

Faccio un esempio (del tutto scolastico - serve solo a capire come funziona): con un'app "Prenotazioni" lato client, l'utente chiede ad un ristorante posto per 4 persone. Il server riceve e memorizza tutte le richieste di prenotazione in un database "Richieste.db" nella tabella "Richieste". Lato ristorante c'è un "client manager" che affida a ciascun client(e) il numero di tavolo.

A questo punto, l'app "Prenotazioni" dovrebbe periodicamente interrogare il server per mezzo di un "GET" per sapere il numero di tavolo.

Cosa farei io:
  1. una volta assegnati tavolo e giorno/ora, questi vengono trasmessi al server, che li immagazzina in una tabella "Assegnazioni" - ipotizzo in un database diverso da "Richieste.db";
  2. per evitare problemi con il GDPR, il database "Assegnazioni.db" (che contiene tutte le assegnazioni tavoli) non può essere scaricata sul client in locale;
Affinché il client sappia che tavolo gli è stato assegnato, il client dovrà interrogare il server. Ma come?
  1. per ciascun user, faccio creare al server un database dedicato (es. "[Username].db") con la tabella "Assegnazioni" popolato con l'estrazione dal database "Assegnazioni.db" e il client scarica solo questo? oppure
  2. c'è un modo con cui il server, interrogato tramite GET, esegua una query e invii il risultato al client, che memorizza su locale ma senza scaricare alcun file?
  3. [soluzione differente che non mi è venuta in mente]?
Quale è più sicuro?

Grazie mille e auguri di buone feste!

PS: il tutto da creare in solo B4X, ovviamente! :)
 

Nicola Ciaramellano

Member
Licensed User
Longtime User
Ciao,
provo a dirti la mia (ma è solo un parere personale):
non userei CloudKVS ma JRDC2 in quanto secondo me CloudKVS è utilissimo in caso di sincronizzazione dei dati, specialmente tra dispositivi mobili e quando non c'è connessione, ma nel caso del tuo esempio è sempre meglio (anzi secondo me doveroso) interrogare il server in tempo reale altrimenti rischi di prenotare un tavolo che non è più disponibile.
Buone feste anche a te :)
 

Elric

Well-Known Member
Licensed User
Ciao Nicola,

intanto grazie del tuo parere!

Se è meglio (secondo te) usare JRDC2... allora per cosa si usa CloudKVS? :oops:

Puoi farmi un esempio?
 

Star-Dust

Expert
Licensed User
Longtime User
Ciao Nicola,

intanto grazie del tuo parere!

Se è meglio (secondo te) usare JRDC2... allora per cosa si usa CloudKVS? :oops:

Puoi farmi un esempio?
KVS serve per avere un buffer dell'archivio localmente. Quando non hai connessione accedi alla copia locale del dati, esegui le operazioni e quando ti ricolleghi si riallinea al database del cloud
 

Nicola Ciaramellano

Member
Licensed User
Longtime User
CloudKVS si usa quando hai più dispositivi che devono accedere allo stesso database e devono essere sincronizzati tra di loro, ma comunque ognuno di loro deve poter funzionare autonomamente anche quando è offline. Per questo motivo tutto il database viene memorizzato su ogni singolo dispositivo - proprio per avere la possibilità di funzionare anche quando si è offline - e tutte le modifiche vengono inviate al server che tiene traccia della data e orario della modifica fatta su ogni singolo dispositivo. In questo modo, quando un dispositivo che era stato offline si ricollega, invia una richiesta al server di tutte (e solo quelle) le modifiche fatte dagli altri dispositivi nel tempo in cui era stato offline. Questo riguarda sia le aggiunte dei records, ma anche le modifiche e le cancellazioni.
Per l'esempio che hai fatto tu, invece, per prima cosa non è necessario che il client riceva tutto il database del ristorante in quanto basta una query al server per sapere solo se ci sono tavoli disponibili e allocarli per quel cliente, se conferma e inoltre non serve lavorare offline proprio perchè l'allocazione deve avvenire in realtime altrimenti, se si è sconnessi non è possibile allocare i posti disponibili.
 

Elric

Well-Known Member
Licensed User
Grazie a entrambi!

Provo a fare un esempio pratico (consapevole che sarà molto più complesso): è il criterio che usa Drive con i GoogleDocs? Lavoro in locale con e sincronizzo solo quando sono online con il server.
 

Star-Dust

Expert
Licensed User
Longtime User
chiede le operazioni di scrittura/modifica successive all'ultimo suo accesso. ogni operazione viene memorizzata con un timestamp.
 

Elric

Well-Known Member
Licensed User
Quindi l'esempio di GoogleDocs è corretto (giusto?). È un sistema simile all'email salvate in cloud con Outlook.

Oppure l'alternativa è che ho capito come funziona ma non ho capito quando si usa...
 

Nicola Ciaramellano

Member
Licensed User
Longtime User
chiede le operazioni di scrittura/modifica successive all'ultimo suo accesso. ogni operazione viene memorizzata con un timestamp.
Ecco, questo è più probabile.
Forse mi sono espresso male, ma è quello che intendevo io, è chiaro che il client non può sapere quali dati siano stati modificati ma come dicevo, il server sequenzia temporalmente tutte le modifiche e il client richiede solo le modifiche operate sul DB dall'ultimo suo collegamento.
Per quanto riguarda Google docs oppure office 365 si in linea di principio l'esempio è proprio quello, ovvero tu puoi modificare i documenti anche offline e questi ultimi poi si sincronizzeranno alla riconnessione. Mentre, per esempio, se usi un servizio di WEBMAIL invece non scarichi tutto il database in locale, ma effettui delle query al server che ti visualizzerà i messaggi richiesti (per esempio gli ultimi n messaggi o il risultato di una ricerca).
 

Elric

Well-Known Member
Licensed User
Intanto Buon Anno!

Grazie mille per le informazioni e le delucidazioni!

Chiaro l'uso del cloud.

Per quanto riguarda, invece, il KVS, se non ho capito male, è un modo per creare un database "NoSQL" e la scelta se usare un KVS piuttosto che tabelle articolate sta tutta nel volere qualcosa di scalabile oppure no. Immagino che il KVS abbia limiti nelle relazionare le tabelle, altrimenti sceglierebbero tutti il KVS invece che il classico SQL.
 

amorosik

Expert
Licensed User
chiede le operazioni di scrittura/modifica successive all'ultimo suo accesso. ogni operazione viene memorizzata con un timestamp.

Mi sembra di capire che hai studiato per benino il sistema CloudKVS
Ma per 'timestamp' intendi un data/ora preso dal device locale?
Perche' se fosse cosi', come viene eseguita la sincronizzazione tra device sconnessi fino ad un attimo fa, ed ora nuovamente connessi?
Nel senso, il device 1 potrebbe avere orologio avanti di 10 minuti, il device 2 potrebbe averlo indietro di 5 minuti, il pc potrebbe avere orologio giusto rispetto al fuso orario locale
E quindi, come 'ragiona' il sistema CloudKvs per la sincronizzazione dei dati?
 

Star-Dust

Expert
Licensed User
Longtime User
Avevo letto qualcosa nel forum qualche tempo fa. Ma non l'ho usato
 

Nicola Ciaramellano

Member
Licensed User
Longtime User
Mi sembra di capire che hai studiato per benino il sistema CloudKVS
Ma per 'timestamp' intendi un data/ora preso dal device locale?
Perche' se fosse cosi', come viene eseguita la sincronizzazione tra device sconnessi fino ad un attimo fa, ed ora nuovamente connessi?
Nel senso, il device 1 potrebbe avere orologio avanti di 10 minuti, il device 2 potrebbe averlo indietro di 5 minuti, il pc potrebbe avere orologio giusto rispetto al fuso orario locale
E quindi, come 'ragiona' il sistema CloudKvs per la sincronizzazione dei dati?
Ciao,
no, in realtà è il server che inserisce nel db il timestamp per cui l'orologio del device è ininfluente. Questo però implica che se più device hanno operato una modifica sullo stesso record mentre erano disconnessi, la modifica che viene presa in considerazione è quella dell'ultimo device che si ri-sincronizza che sovrascrive tutte le altre, anche se non è quello che ha fatto la modifica per ultimo quando non era collegato.
 

udg

Expert
Licensed User
Longtime User
Premetto di non aver mai utilizzato KVS/CloudKVS e, soprattutto, di non aver sbirciato nel codice. Quindi ciò che dico potrebbe essere errato.
Stando ad uno dei primi post presenti nel tutorial relativo a CloudKVS, si legge:

Each item has a time stamp. The time value is set when the item is added to the local store.
The remote store compares the time stamp with the existing item time and updates it if it is newer.


Ciò induce a pensare che in origine il timestamp sia locale. Questo viene inviato al server che verifica se sia successivo o meno a quello eventualmente esistente e quindi decide se aggiornare i dati.
Da considerare che il timestamp è GMT e quindi non risente del fuso orario dove si trovino i client.

Si potrebbe condurre un semplice esperimento per verificare quanto sopra utilizzando un client con data/ora corretti ed un secondo client con data/ora nel futuro (ad esempio). Il secondo si sincronizza e poco dopo lo fa anche il primo. Sul server dovrebebro rimanere i dati del client "falsato" (perché più recenti). In tal modo, manipolando data/ora di un client si possono "sovrascrivere" i dati di tutti gli altri (che condividono user+key).

La questione sincronizzazione è da valutare con attenzione in funzione dell'applicazione.
Ad esempio, nel caso si usi lo store per gestire la giacenza di un articolo (o la disponibilità di un tavolo al ristorante, visto l'interesse spesso suscitato dall'argomento..) è facile anticipare i problemi che ne potrebbero derivare.
Utente1 vede (localmente) che il tavolo è disponibile e prenota. Al momento non può sincronizzare
Utente2 vede (localmente) che il tavolo è disponibile e prenota. L'operazione avviene ad un tempo successivo a quello di Utente1.
Utente2 sincronizza. Il server conserva il timestamp e il fatto che il tavolo va a Utente2
Utente1 sincronizza. Il server vede che si riferisce ad un timestamp meno recente e scarta l'update.
Utente1 va al ristorante e il tavolo è occupato da Utente2 :-(
ps: ammettedno che Utente1 riceva un apposito messaggio in fase di sincro ("la tua prenotazione è fallita") dovrebbe cercare di riprenotare e troverebbe occupato. Finché ha margine di tempo, magari non se la prende. Ma se gli si brucia la serata...
 

Nicola Ciaramellano

Member
Licensed User
Longtime User
Premetto di non aver mai utilizzato KVS/CloudKVS e, soprattutto, di non aver sbirciato nel codice. Quindi ciò che dico potrebbe essere errato.
Stando ad uno dei primi post presenti nel tutorial relativo a CloudKVS, si legge:

Each item has a time stamp. The time value is set when the item is added to the local store.
The remote store compares the time stamp with the existing item time and updates it if it is newer.


Ciò induce a pensare che in origine il timestamp sia locale. Questo viene inviato al server che verifica se sia successivo o meno a quello eventualmente esistente e quindi decide se aggiornare i dati.
Da considerare che il timestamp è GMT e quindi non risente del fuso orario dove si trovino i client.

Si potrebbe condurre un semplice esperimento per verificare quanto sopra utilizzando un client con data/ora corretti ed un secondo client con data/ora nel futuro (ad esempio). Il secondo si sincronizza e poco dopo lo fa anche il primo. Sul server dovrebebro rimanere i dati del client "falsato" (perché più recenti). In tal modo, manipolando data/ora di un client si possono "sovrascrivere" i dati di tutti gli altri (che condividono user+key).

La questione sincronizzazione è da valutare con attenzione in funzione dell'applicazione.
Ad esempio, nel caso si usi lo store per gestire la giacenza di un articolo (o la disponibilità di un tavolo al ristorante, visto l'interesse spesso suscitato dall'argomento..) è facile anticipare i problemi che ne potrebbero derivare.
Utente1 vede (localmente) che il tavolo è disponibile e prenota. Al momento non può sincronizzare
Utente2 vede (localmente) che il tavolo è disponibile e prenota. L'operazione avviene ad un tempo successivo a quello di Utente1.
Utente2 sincronizza. Il server conserva il timestamp e il fatto che il tavolo va a Utente2
Utente1 sincronizza. Il server vede che si riferisce ad un timestamp meno recente e scarta l'update.
Utente1 va al ristorante e il tavolo è occupato da Utente2 :-(
ps: ammettedno che Utente1 riceva un apposito messaggio in fase di sincro ("la tua prenotazione è fallita") dovrebbe cercare di riprenotare e troverebbe occupato. Finché ha margine di tempo, magari non se la prende. Ma se gli si brucia la serata...
Hai ragione, in effetti non avevo letto la precisazione di Erel e a questo punto, per curiosità sono andato a guardare il codice sul client:

B4X:
Private Sub CreateItem (user As String, key As String, value() As Byte) As Item
    Dim i As Item
    i.Initialize
    i.UserField = user
    i.KeyField = key
    i.ValueField = value
    i.idField = -1
    i.TimeField = DateTime.Now
    Return i
End Sub

Ed in effetti il timestamp viene dato dal singolo client, pensavo invece erroneamente che fosse il server a dare il timestamp proprio per evitare errori di sincronizzazione con i clients che potrebbero avere orari sbagliati.
 

Nicola Ciaramellano

Member
Licensed User
Longtime User
Giusto come precisazione, lato server ho visto che viene usato anche questo codice:

B4X:
sql.ExecNonQuery2("INSERT OR REPLACE INTO data VALUES (?, ?, ?, ?, ?)",  _
            Array (item.UserField, item.KeyField, item.ValueField, id, Min(item.TimeField, DateTime.Now)))

Che consente di non considerare il timestamp di un client se quest'ultimo è impostato nel futuro, ma di rimpiazzarlo con quello attuale, sempre se si fa attenzione a tenere almeno aggiornato quello del server.
 
Top