Search code examples
scalaexceptionmonix

How to make monix fixed rate Scheduler continue upon failure


I am just starting to use monix, in part for scheduling repeated work in a long running app. I will manage exceptions but I would like that monix continue calling the given function even if I let pass some of them.

Now, from a simple test, once a repeated call is scheduled, it won't continue calling it once an exception arise :

// will print "Hi" repeatedly
scheduler.scheduleAtFixedRate(5.milliseconds, 2.milliseconds) {
  println("Hi")
}

// will print "Hi" only once
scheduler.scheduleAtFixedRate(5.milliseconds, 2.milliseconds) {
  println("Hi")
  throw new RuntimeException("oups, forgot to catch that one")
}

Note: I create the scheduler to log exceptions and errors

EDIT:

I realize that it's a poor design to simply repeat that task upon failure. Instead I should actually setup a proper exception management system, with delayed restart.

Now, I don't see any functionalities in Monix to do that. So I'll have to do it my-self. I let the question in case someone has the same issue, and in case someone knows of a monix tooling that can be useful.


Solution

  • You can always leverage scala.util.Try for that or simple try-catch blocks. On any failure case, you just log and move on. You can even have failure retry strategy as below.

    import scala.util._
    
    def taskExceptionProne() = ???
    
    var failures = 0
    val maxRetries = 10
    
    scheduler.scheduleAtFixedRate(5.milliseconds, 2.milliseconds) {
        Try(taskExceptionProne) match {
            Success(result) =>
                //do something with the result
                failures = 0
                println("Task executed.")
            Failure(throwable) =>
                if (failures>=maxRetries) throw throwable else {
                    failures = failures + 1
                    //log failure
                    println(throwable.getMessage)
                }
        }
    }