Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Recursive call for try in scala

Tags:

xml

scala

Problem 1 ) I am trying to extract currency from YQL in scala. getXML mentioned below takes the rest URL and returns the xml node. In my main code i would like to call getXML again in case failure happens after a sleep of 10000 milli seconds.

Kindly advise how can be achieved as when i am trying to make a getXML inside the failure code is not compiling.

def getXML(url: String): Try[scala.xml.Node] =  
 {

 Try(XML.loadString(Source.fromURL(new URL(url)).mkString))

 }


val nodes = getXML(ccyurl) match {
  case Success(node) => node
  case Failure(f) => {
      Thread.sleep(10000)
      /****/
}  

Problem 2) One more question. I am new to programming and that too scala so stumbling a bit. I have defined a function

def exchangelookup(s :String): Try[String] = Try(exchange_currency_map(s))

Its use is coming like mentioned below and it is a item 4 in an array.

exchangelookup(Cols(0).takeRight(3)) match {case Success(x) => x
                               case Failure(x) =>       FileParserlogger.error(x.getMessage()) } , //ExchangeCurrency 4

But when i am using this in another array as static(4) i am getting "type mismatch; found : Any required: String"

val fxconversion = fxconvertor(getexchange(nodes,static(10)),getexchange(nodes, exchange_to_real_ccy_map.getOrElse(static(4),static(4))))

Thanks in advance.

like image 442
user3341078 Avatar asked Jan 23 '26 11:01

user3341078


1 Answers

You need to use recoverWith to recover from a Failure with another Try. A simple usage would look like this:

def getXML(url: String): Try[scala.xml.Node] = {
    Try(XML.loadString(io.Source.fromURL(new URL(url)).mkString))
        .recoverWith {
            case _ => {Thread.sleep(10000); getXML(url)}
        }
}

However, this will run forever if it never succeeds (and by forever, I mean until it hits a stack overflow from recursing too deeply), which we probably don't want. It would be easy, however to add a counter for max retries:

def getXML(url: String)(retries: Int): Try[scala.xml.Node] = {
    Try(XML.loadString(io.Source.fromURL(new URL(url)).mkString))
        .recoverWith {
            case _ if(retries > 0) => {
                Thread.sleep(10000)
                getXML(url)(retries - 1)
            }
        }
}

Another potential problem with this is that it's blocking code. Depending on your use case, that might be okay, but if your program has the need for concurrency, you might consider using Future instead of Try. The implementation of getXML would be almost exactly the same, though it's usage would be quite different.

like image 156
Michael Zajac Avatar answered Jan 26 '26 04:01

Michael Zajac



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!