What's the Scala way to implement a retry-able call like this one?

前端 未结 14 1736
甜味超标
甜味超标 2020-11-29 16:08

Still the newbie in Scala and I\'m now looking for a way to implement the following code on it:

@Override
public void store(InputStream source, String destin         


        
14条回答
  •  猫巷女王i
    2020-11-29 16:53

    Here is one possible implementation:

    def retry[T](times: Int)(fn: => T) = 
        (1 to times).view flatMap (n => try Some(fn) catch {case e: Exception => None}) headOption
    

    You can use it like this:

    retry(3) {
        getClient.putObject(request)
    }
    

    retry also returns Some[T] if body was processed successfully and None if body was only throwing exceptions.


    Update

    If you want to bobble up last exception, then you can take very similar approach but use Either instead of Option:

    def retry[T](times: Int)(fn: => T) = {
        val tries = (1 to times).toStream map (n => try Left(fn) catch {case e: Exception => Right(e)}) 
    
        tries find (_ isLeft) match {
            case Some(Left(result)) => result
            case _ => throw tries.reverse.head.right.get
        }
    }
    

    Also, as you can see, at the end, instead of having only last exception, I have them all. So you can also wrap them in some AggregatingException if you want and then throw it. (for simplicity, I just throw last exception)

提交回复
热议问题