Reactive Scala Driver for MongoDB

Asynchronous & Non-Blocking

Failover Strategy

A FailoverStrategy defines if and how many times should ReactiveMongo retry a database operation (query, insertion, command, etc.) that failed for the following reasons:

The other causes (business errors, normal database errors, fatal errors, etc.) are not handled.

FailoverStartegy is a case class defined as follows:

package api

import scala.concurrent.duration._

/**
 * A failover strategy for sending requests.
 *
 * @param initialDelay the initial delay between the first failed attempt and the next one.
 * @param retries the number of retries to do before giving up.
 * @param delayFactor a function that takes the current iteration and returns a factor to be applied to the initialDelay.
 */
case class FailoverStrategy(
  initialDelay: FiniteDuration = 500 milliseconds,
  retries: Int = 5,
  delayFactor: Int => Double = n => 1)

The default FailoverStrategy retries 5 times, with 500 ms between each attempt. Let’s say that we want to define a FailoverStrategy that waits more time before a new attempt:

import scala.concurrent.duration._

import reactivemongo.api.FailoverStrategy

val strategy =
  FailoverStrategy(
    initialDelay = 500 milliseconds,
    retries = 5,
    delayFactor =
      attemptNumber => 1 + attemptNumber * 0.5
  )

This strategy retries at most 5 times, waiting for initialDelay * ( 1 + attemptNumber * 0.5 ) between each attempt (attemptNumber starting from 1). Here is the way the attempts will be run:

You can specify a strategy by giving it as a parameter to connection.db or db.collection:

import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global

import reactivemongo.api.FailoverStrategy

val defaultStrategy = FailoverStrategy()

val customStrategy =
  FailoverStrategy(
    initialDelay = 500 milliseconds,
    retries = 5,
    delayFactor =
      attemptNumber => 1 + attemptNumber * 0.5
  )

def connection1: reactivemongo.api.MongoConnection = ???

// database-wide strategy
val db1 = connection1.db("dbname", customStrategy)

// collection-wide strategy
val db2 = connection1.db("dbname", defaultStrategy)
val collection = db2.collection("collname", customStrategy)