Italian [REST-API]#DowloadTime

luke2012

Well-Known Member
Licensed User
Longtime User
App Nativa ---> Drupal (REST-API)
https://www.drupal.org/docs/drupal-apis

Premetto che è la prima app che sviluppo che và a leggere su un server Drupal e mi sono da subito un pò dovuto confrontare con l'ottimizzazione dell'app per quanto riguarda i tempi di dowload dei dati.
Su drupal ogni singolo set di dati contenuto nelle pagine del CMS viene chiamato "nodo" di dati che contiene tutti i campi (sia visibili sulla pagina web che di sistema).
L'app già subito in partenza, deve scaricarsi 40 nodi in sequenza uno ad uno (peso medio 2,6 kb):

'DOWNLOAD NODO
Dim j As HttpJob : j.Initialize("j", Me)
private WSUrl = https://dominio.com//node/18?_format=json
J.Download (WSUrl)

Facendo delle verifiche, ogni singolo download di un nodo ci mette in media 600 ms che moltiplicato per il totale dei nodi fà 24.000 ms in totale ovvero 24 secondi.
L'utente che apre l'app la prima volta deve aspettare 24 secondi prima di poter iniziare a usarla, tradotto in utentese: un'eternità.
In questo caso, teoricamente, si può agire in 2 modi:

1) Lato server
2) Lato client

LATO SERVER (non sotto il mio controllo)
- E' il mio primissimo progetto (client) su Drupal (che usa il mio cliente) e di drupal ho conoscenze molto limitate, ovvero: installazione di base del modulo applicativo delle API e la url (//node/18?_format=json) di come chiedere un nodo in JSON a Drupal).
- L'hosting (drupal) non è in mia gestione ma è in gestione ad un azienda esterna (fornitore dell'azienda che mi ha commissionato l'app).

LATO CLIENT (sotto il mio controllo)
Qui sapendo come diavolo
?
ottimizzare il download dei dati, potrei risparmiare un pò di prezioso tempo.
La prima cosa che mi viene in mente è quella di chiamare un solo download passando tutti i nodi come parametri, invece di eseguire 40 download per tutti i 40 nodi.
In teoria in questo modo dovrei risparmiare i tempi di rete (richiesta e riposta) moltiplicati per 40 volte. Sbaglio ?

Detto a parole sembra semplice ma... come diavolo dire alle API
?
?
?
Drupal di darmi 40 nodi invece che uno ?
?

Stavo controllando la documentazione ma fino ad ora non ho trovato la
?
di volta
?


Qualcuno di voi si è mai confrontato con questo tipo di problematiche?

1636656239685.png
 

Star-Dust

Expert
Licensed User
Longtime User
Anziché farli in sequenza hai provato fare download in parallelo?

Un introduzione animata che maschera i primi 10 secondi di download?
 

luke2012

Well-Known Member
Licensed User
Longtime User
Anziché farli in sequenza hai provato fare download in parallelo?

Un introduzione animata che maschera i primi 10 secondi di download?

1) "Anziché farli in sequenza..."
Per capirci io uso "OkHttpUtils2 with Wait For": https://www.b4x.com/.../b4x-okhttputils2-with-wait-for.../

B4X:
Public Sub Initialize 'Class
    Download1
End sub

Sub Download1 As ResumableSub
    For Each nid As Int In nidsList
        Wait For (GetContent (nid, user, psw)) Complete (Content1 As Map)
    Next
End Sub

Sub GetContent (nid As Int, aUser As String, aPsw As String) As ResumableSub

    Wait For (GetJSONByNID (nid, aUser, aPsw)) Complete (WSResult As String)
    Private WSResponse As String = WSResult
    '......
  
end sub

Sub GetJSONByNID (nid As Int, aUser As String, aPsw As String) As ResumableSub

    Dim j As HttpJob : j.Initialize("j", Me)
    j.Username = aUser
    j.Password = aPsw
    Private WSNodeURL As String = WebHostURL & "/node/"
    Private WSFormat As String = "?_format=json"
    Private WSUrl As String = WSNodeURL & nid & WSFormat

    j.Download (WSUrl)
    'Log ("GetJSONByNID | WSUrl: " & WSUrl)

    Wait For (j) JobDone(j As HttpJob)
    If j.Success Then
        Private WSResponse As String = j.GetString2("UTF8")
        'Log ("GetJSONByNID | WSResponse " & WSResponse)
    End If
    j.Release

   'Parse JSON....

End Sub

Per intenderci, il codice principale che scarica i nodi (drupal) tramite rest api è quello sopra.

2) Già implementata. Ma il problema è che quando l'abbiamo implementata avevamo stimato che bastavano 8 secondi di animazione (che tenevano impegnato l'utente nell'attesa) e poi i dati erano pronti (scaricati e in cache) nell'app.
Premetto che questo accade solo la prima volta che si avvia l'app, poi i dati vengono tenuti in cache (mappe nell'app).

Ora ci siamo accorti (io e l'altra persona che stiamo lavorando sul progetto) che tempi di download sono raddoppiati e stiamo cercando di capire il perchè anche scrivendo all'azienda che gestisce l'hosting (server dedicato dove gira drupal + modulo rest api).
 
Last edited:

sirjo66

Well-Known Member
Licensed User
Longtime User
io farei così:
dichiari 8 oggetti HttpJob, esegui tutti e 8 i comandi di Download e poi:
B4X:
Wait For (j1) JobDone(j1 As HttpJob)
Wait For (j2) JobDone(j2 As HttpJob)
Wait For (j3) JobDone(j3 As HttpJob)
Wait For (j4) JobDone(j4 As HttpJob)
Wait For (j5) JobDone(j5 As HttpJob)
Wait For (j6) JobDone(j6 As HttpJob)
Wait For (j7) JobDone(j7 As HttpJob)
Wait For (j8) JobDone(j8 As HttpJob)

Cioè li aspetti tutti e 8
poi fai il If J1.Success Then.... per tutti e 8 gli oggetti leggendoti il risultato

Poi parti con altri 8 e via così
In tre volte li hai fatti tutti e 24

Questa la soluzione più semplice, io personalmente utilizzerei sì 8 oggetti HttpJob ma poi gestirei il tutto con l'evento JobDone (alla vecchia maniera) in modo che appena uno ha finito il suo dovere chiama l'evento, e lì dentro ne faccio partire subito un altro, ma questo comporta un lavoro un po' più impegnativo
 

Star-Dust

Expert
Licensed User
Longtime User
io farei così:
dichiari 8 oggetti HttpJob, esegui tutti e 8 i comandi di Download e poi:
B4X:
Wait For (j1) JobDone(j1 As HttpJob)
Wait For (j2) JobDone(j2 As HttpJob)
Wait For (j3) JobDone(j3 As HttpJob)
Wait For (j4) JobDone(j4 As HttpJob)
Wait For (j5) JobDone(j5 As HttpJob)
Wait For (j6) JobDone(j6 As HttpJob)
Wait For (j7) JobDone(j7 As HttpJob)
Wait For (j8) JobDone(j8 As HttpJob)

Cioè li aspetti tutti e 8
poi fai il If J1.Success Then.... per tutti e 8 gli oggetti leggendoti il risultato

Poi parti con altri 8 e via così
In tre volte li hai fatti tutti e 24

Questa la soluzione più semplice, io personalmente utilizzerei sì 8 oggetti HttpJob ma poi gestirei il tutto con l'evento JobDone (alla vecchia maniera) in modo che appena uno ha finito il suo dovere chiama l'evento, e lì dentro ne faccio partire subito un altro, ma questo comporta un lavoro un po' più impegnativo
Quello che intendevo io, ma per farle seguire in parallelo ogni waitfor deve essere messo all'interno di una sub

Nel modo in cui l'ha fatto tu il successivo non parte se non ha concluso il precedente
 
Top