All Projects → softwaremill → Retry

softwaremill / Retry

Licence: mit
because you should never give up, at least not on the first try

Programming Languages

scala
5932 projects
scalajs
39 projects

Projects that are alternatives of or similar to Retry

Gollback
Go asynchronous simple function utilities, for managing execution of closures and callbacks
Stars: ✭ 55 (-81.85%)
Mutual labels:  future, retry
Tenacity
Retrying library for Python
Stars: ✭ 3,472 (+1045.87%)
Mutual labels:  retry
Austen-Works
Jane Austen’s Collected Works
Stars: ✭ 26 (-91.42%)
Mutual labels:  future
awsretry
Decorate your AWS Boto3 Calls with AWSRetry.backoff(). This will allows your calls to get around the AWS Eventual Consistency Errors.
Stars: ✭ 42 (-86.14%)
Mutual labels:  retry
retry
Simple and easy retry mechanism package for Go
Stars: ✭ 54 (-82.18%)
Mutual labels:  retry
Promises
It's just another Promise library...
Stars: ✭ 43 (-85.81%)
Mutual labels:  future
HTMLTestRunner cn
HTMLTestRunner 汉化版,同时支持python 2和3,增加截图展示功能,失败重试
Stars: ✭ 191 (-36.96%)
Mutual labels:  retry
Retry Axios
🦖 A super flexible interceptor for Axios that makes it easy to retry requests.
Stars: ✭ 296 (-2.31%)
Mutual labels:  retry
asynqro
Futures and thread pool for C++ (with optional Qt support)
Stars: ✭ 103 (-66.01%)
Mutual labels:  future
sisyphus
The java retry framework.(支持注解的 java 重试框架)
Stars: ✭ 126 (-58.42%)
Mutual labels:  retry
perseverance
Make your functions 💪 resilient and 🚥 fail-fast to 💩 failures or ⌚ delays
Stars: ✭ 12 (-96.04%)
Mutual labels:  retry
re-retrying
A Java library to allow for the creation of configurable retrying strategies for an arbitrary function call, such as something that communicates with a remote service with flaky uptime.
Stars: ✭ 36 (-88.12%)
Mutual labels:  retry
java-retrying
java retry module, based on guava-retrying, support sync/async retry
Stars: ✭ 19 (-93.73%)
Mutual labels:  retry
f
a library to write async vert.x code similar as using java syntax
Stars: ✭ 22 (-92.74%)
Mutual labels:  future
Flutter advanced networkimage
flutter advanced network image provider
Stars: ✭ 282 (-6.93%)
Mutual labels:  retry
backoff
PHP library providing retry functionality with multiple backoff strategies and jitter support
Stars: ✭ 132 (-56.44%)
Mutual labels:  retry
resilience4clj-circuitbreaker
Resilience4Clj circuit breaker lets you decorate a function call (usually with a potential of external failure) with a safety mechanism to interrupt the propagation of failures.
Stars: ✭ 40 (-86.8%)
Mutual labels:  retry
threadpool
Golang simple thread pool implementation
Stars: ✭ 68 (-77.56%)
Mutual labels:  future
Retry
♻️ The most advanced interruptible mechanism to perform actions repetitively until successful.
Stars: ✭ 294 (-2.97%)
Mutual labels:  retry
Future
Streamlined Future<Value, Error> implementation
Stars: ✭ 291 (-3.96%)
Mutual labels:  future

retry

Build Status

don't give up

install

With sbt, add the following to your project's build.sbt

libraryDependencies += "com.softwaremill.retry" %% "retry" % "0.3.3"

usage

Applications fail. Network connections drop. Connections timeout. Bad things happen.

Failure to address this will cause other bad things to happen. Effort is the measurement of how hard you try.

You can give your application perseverance with retry.

Retry provides interfaces for common retry strategies that operate on Scala Futures.

Basic usage requires three things

  • an implicit execution context for executing futures
  • a definition of Success encode what "success" means for the type of your future
  • a block of code that results in a Scala Future.

Depending on your strategy for retrying a future you may also need an odelay.Timer for asynchronously scheduling followup attempts

Retry provides a set of defaults that provide retry.Success definitions for Option, Either, Try, and a partial function (defined with Success.definedAt(partialFunction)) out of the box.

import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future

retry.Backoff().apply(() => Future {
  // something that can "fail"
})

Defining success

Retry needs to know what success means in the context of your Future in order to know when to retry an operation.

It does this through a generic Success[-T](pred: T => Boolean) type class, where T matches the type your Future will resolve to.

Retry looks for this definition within implicit scope of the retry.

You may wish define an application-specific definition of what "success" means for your future. You can do so by specifying the following in scope of the retry.

implicit val perfectTen = Success[Int](_ == 10)

If your future completes with anything other than 10, it will be considered a failure and will be retried. Here's to you, tiger mom!

Success values may also be composed with and and or semantics

// will be considered a success when the preconditions of both successA and successB are met
val successC = successA.and(successB)

// will be considered a success when the predconditions of either successC or successD are met
val successE = successC.or(successD)

Sleep schedules

Rather than blocking a thread, retry attempts are scheduled using Timers. Your application may run within a platform that provides its own way for scheduling tasks. If an odelay.jdk.JdkTimer isn't what you're looking for, you may wish to use the odelay.Timer for netty, odelay.netty.Timer in the odelay-netty module or an odelay.twitter.TwitterTimer available in the odelay-twitter module.

See the odelay docs for defining your own timer. If none of these aren't what you're looking for, please open a pull request!

According to Policy

Retry logic is implemented in modules whose behavior vary but all produce a common interface: a retry.Policy.

trait Policy {
  def apply[T](promise: () => Future[T])
     (implicit success: Success[T],
      executor: ExecutionContext): Future[T]
}

Directly

The retry.Directly module defines interfaces for retrying a future directly after a failed attempt.

// retry 4 times
val future = retry.Directly(4) { () =>
  attempt
}

Pause

The retry.Pause module defines interfaces for retrying a future with a configurable pause in between attempts

// retry 3 times pausing 30 seconds in between attempts
val future = retry.Pause(3, 30.seconds).apply { () =>
  attempt
}

Backoff

The retry.Backoff modules defines interfaces for retrying a future with a configureable pause and exponential backoff factor.

// retry 4 times with a delay of 1 second which will be multipled
// by 2 on every attempt
val future = retry.Backoff(4, 1.second).apply { () =>
  attempt
}

When

All of the retry strategies above assume you are representing failure in your Future's result type. In cases where the result of your future is "exceptional". You can use the When module which takes a PartialFunction of Any to Policy.

val policy = retry.When {
  case NonFatal(e) => retry.Pause(3, 1.second)
}

policy(execptionalAttempt)

Note, The domain of the PartialFunction passed to When may cover both the exception thrown or the successful result of the future.

Suggested library usage

Since all retry modules now produce a generic interface, a retry.Policy, if you wish to write clients of services you may wish to make define a Success for the type of that service and capture an configurable reference to a Policy so that clients may swap policies based on use case.

case class Client(retryPolicy: retry.Policy = retry.Directly()) {
  def request = retryPolicy(mkRequest)
}

val defaultClient = Client()

val customClient = defaultClient.copy(
  retryPolicy = retry.Backoff()
)

Credits

Originally created by Doug Tangren, maintained by SoftwareMill.

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].