2016-05-09 32 views
5

Sto provando ad usare i nuovi stream di Akka e mi chiedo come posso usare e restituire la coda di Source al chiamante senza materializzarlo nel mio codice?Come posso utilizzare e restituire la coda di origine al chiamante senza materializzarlo?

Immaginate di avere una libreria che effettua il numero di chiamate asincrone e restituisce risultati tramite Source. Funzione simile a questa

def findArticlesByTitle(text: String): Source[String, SourceQueue[String]] = { 

    val source = Source.queue[String](100, backpressure) 

    source.mapMaterializedValue { case queue => 

    val url = s"http://.....&term=$text" 
    httpclient.get(url).map(httpResponseToSprayJson[SearchResponse]).map { v => 
     v.idlist.foreach { id => 
     queue.offer(id) 
     } 

     queue.complete() 
    } 
    } 

    source 
} 

e chiamante potrebbe usare in questo modo

// There is implicit ActorMaterializer somewhere 
val stream = plugin.findArticlesByTitle(title) 
val results = stream.runFold(List[String]())((result, article) => article :: result) 

Quando ho eseguito questo codice all'interno mapMaterializedValue non viene mai eseguito.

Non riesco a capire perché non ho accesso all'istanza di SourceQueue se dovrebbe essere il chiamante a decidere come materializzare la fonte.

Come devo implementarlo?

+0

Qual è il motivo per inserire la coda quando il valore è materializzato, invece di scorrere i risultati e generare la sorgente da questo iterabile, qualcosa come 'val ids: Iterable [String] = httpclient.get (url) .map (...); val source = Source.from (ids) '? – devkat

+0

L'uso della raccolta di cemento diminuisce l'idea di 'Fonte' che presuppone l'arrivo di oggetti qualche tempo dopo. Immaginare la funzione di libreria restituirà migliaia di miliardi di documenti. Il cliente dovrebbe essere in grado di elaborarli come vengono. – expert

risposta

5

Nell'esempio di codice si restituisce l'origine anziché il valore restituito di source.mapMaterializedValue (la chiamata al metodo non modifica l'oggetto Source).

+3

BTW, nel tuo esempio di codice stai mantenendo 'source' invece del valore di ritorno di' source.mapMaterializedValue' (la chiamata al metodo non muta l'oggetto 'Source'). Non sono sicuro se questo è lo stesso nel tuo codice attuale. – devkat

+0

Era 'mapMaterializedValue'. Grazie! Ho aggiornato la tua risposta con ciò che mi hai detto in commento, così posso accettarlo. – expert