Ausgabe
Ich versuche, diese sequentielle und schnelle Lösung zu parallelisieren:
for
cellTowersPayload <- CellHintTransformer.createGoogleApiPayload(cellAndWifiHints.cellHints).mapError(mapRequirementsFailure)
googleMapsResultCellTowers <- googleMapsApi.call(cellTowersPayload)
wifiHintsPayload <- WlanHintTransformer.createGoogleApiPayload(cellAndWifiHints.wifiHints).mapError(mapRequirementsFailure)
googleMapsResultWifiHints <- googleMapsApi.call(wifiHintsPayload) // TODO paralleize with call cell towers
mappedResult <- mapResult(googleMapsResultCellTowers, googleMapsResultWifiHints)
yield mappedResult
Die resultierende Lösung sollte die beiden Aufrufe parallel durchführen und beide Ergebnisse zurückgeben (die jeweils Erfolg oder Fehler sein können). Also kein schnelles Scheitern, wenn einer der Anrufe fehlschlägt
Wie mache ich das idiomatisch in ZIO?
Lösung
Hier gibt es also zwei Dinge. Sie können Operationen parallel ausführen, indem .fork
Sie auf dem ZIO verwenden, das Sie parallelisieren möchten, und dann die Verbindung auf diesen gegabelten Fasern durchführen.
Das Problem ist, dass Sie irgendwie sicherstellen müssen, dass beide ausgeführt werden, auch wenn die andere fehlschlägt. ZIO bricht standardmäßig eine andere Faser ab, wenn eine der Fasern die Berechnungen nicht minimiert. Wir können etwas wie verwenden .either
, um sicherzustellen, dass ZIO nie ausfällt, sondern stattdessen zurückkehrt Either[E, A]
.
Also würden wir so etwas tun:
for {
zio1 <- firstOperation().fork().either
zio2 <- secondOperation().fork().either
result <- zio1.zip(zio2)
tupleResult <- result.join
} yield tupleResult
Beantwortet von – Dominik Wosiński
Antwort geprüft von – Dawn Plyler (FixError Volunteer)