On Sat, Oct 13, 2012 at 8:57 AM, √iktor Ҡlang <
viktor...@gmail.com> wrote:
>
>
> On Sat, Oct 13, 2012 at 12:46 AM, Daniel Sobral <
dcso...@gmail.com> wrote:
>>
>> Following up on my experience with Dispatch 0.9.x's Promise, which is
>> pretty much like SIP-14's Future, there's something that's bothering
>> me about Future and Try: it's not dead-easy to transform a Future[T]
>> into a Future[Option[T]] or Future[Either[Exception, T]] as a way of
>> handling exceptions that may have occurred, and it's hard to convert a
>> Try[T] into a Try[Either[Exception, T]] as well.
>>
>> I've used these features a lot, and I'm wondering if there's something
>> I'm missing, or if they are something Future/Try are missing.
>
>
> Could you please enumerate the actual use-cases (should be simple enough if
> you've used them a lot)?
>
> I'm quite sure Futures cover all the use-cases, so give me your best shot!
Ok, let's see. First, either.
This one transforms turns an error result into an empty string, which
is a good enough default for the upstream, plus log errors.
Http(request.HEAD OK header("Last-Modified")).either map {
case Right(something) => something
case Left(ex) =>
logger error "%s: erro ao verificar data de alteração:
%s".format(request.build().getUrl, ex)
""
}
And this one turns an error result into a None (the successful result
is an Option), and log errors.
val httpResponse = Http(request.GET OK header("Last-Modified")).either
httpResponse.map {
case Right(something) => something
case Left(ex) =>
logger error "%s: erro no download:
%s".format(request.build().getUrl, ex)
None
}.apply()
This is similar to the above, except that the the success is not an
Option (pun intended):
(db consulta DBInfo("monitoramento", "monitorado",
None)).either.apply() match {
case Right(resultado) => Some(parse(resultado))
case Left(ex) => logger error "Erro ao obter municípios
monitorados: %s".format(ex.getMessage); None
The next, and final, two just produces different logging messages
based on success/failure:
val respostas = urls map { cockpitUrl =>
cockpitUrl ->
Http(url(cockpitUrl).POST.setBody(json).setHeader("content-type",
"application/json") OK as.String).either
}
respostas foreach {
case (cockpitUrl, resposta) =>
resposta foreach {
case Left(ex) => // TODO: retry?
logger error "%s: erro na notificação: %s (ids perdidos:
%s)".format(cockpitUrl, ex, ids mkString ", ")
case _ =>
logger trace "Notificado %s com %s".format(cockpitUrl, ids
mkString ", ")
}
}
val resultadoDaPersistencia = (db insere (dbInfo, dadosAGravar)).either
resultadoDaPersistencia foreach {
case Right(_) =>
logger trace "Persistido %s/%s/%s".format(dbInfo.indice,
dbInfo.tipo, dbInfo.id getOrElse "")
case Left(ex) =>
logger error "Falha ao persistir
%s/%s/%s!".format(dbInfo.indice, dbInfo.tipo, dbInfo.id getOrElse "")
}
As for ".option", I have a single use outside tests, where I just
don't care whether I got an error or not:
def consultaNode(hostname: String): Option[String] =
http(host(hostname, portaDoElasticSearch) / "_cluster" / "nodes"
OK as.String).option.apply()
I had more of those, but they progressively because ".either", to
produce logging.