All Projects → lerouxrgd → Recloser

lerouxrgd / Recloser

Licence: mit
A concurrent circuit breaker implemented with ring buffers

Programming Languages

rust
11053 projects

Projects that are alternatives of or similar to Recloser

Falcon
A high-performance web server for Ruby, supporting HTTP/1, HTTP/2 and TLS.
Stars: ✭ 2,058 (+3935.29%)
Mutual labels:  async, concurrent
Rubico
[a]synchronous functional programming
Stars: ✭ 133 (+160.78%)
Mutual labels:  async, concurrent
Hitchcock
The Master of Suspense 🍿
Stars: ✭ 167 (+227.45%)
Mutual labels:  async, concurrent
Tascalate Concurrent
Implementation of blocking (IO-Bound) cancellable java.util.concurrent.CompletionStage and related extensions to java.util.concurrent.ExecutorService-s
Stars: ✭ 144 (+182.35%)
Mutual labels:  async, concurrent
Arq
Fast job queuing and RPC in python with asyncio and redis.
Stars: ✭ 695 (+1262.75%)
Mutual labels:  async, concurrent
Uvicorn Gunicorn Fastapi Docker
Docker image with Uvicorn managed by Gunicorn for high-performance FastAPI web applications in Python 3.6 and above with performance auto-tuning. Optionally with Alpine Linux.
Stars: ✭ 1,014 (+1888.24%)
Mutual labels:  async
Cvdm.errorhandling
[DEPRECATED, use FsToolkit.ErrorHandling] AsyncResult and Result computation expressions and helper functions for error handling in F#
Stars: ✭ 47 (-7.84%)
Mutual labels:  async
Uvloop
Ultra fast asyncio event loop.
Stars: ✭ 8,246 (+16068.63%)
Mutual labels:  async
Fastapi
FastAPI Tutorials & Deployment Methods to Cloud and on prem infrastructures
Stars: ✭ 41 (-19.61%)
Mutual labels:  async
Compojure Api
Sweet web apis with Compojure & Swagger
Stars: ✭ 1,056 (+1970.59%)
Mutual labels:  async
Before After Hook
wrap methods with before/after hooks
Stars: ✭ 49 (-3.92%)
Mutual labels:  async
Fgbase
Ready-send coordination layer on top of goroutines.
Stars: ✭ 45 (-11.76%)
Mutual labels:  concurrent
Elixirbooks
List of Elixir books
Stars: ✭ 1,021 (+1901.96%)
Mutual labels:  concurrent
Emacs Async Await
Async/Await for Emacs
Stars: ✭ 47 (-7.84%)
Mutual labels:  async
Scout
Friendly fuzzy finder made in rust
Stars: ✭ 43 (-15.69%)
Mutual labels:  async
Protobuffer
A simple wrapper library for protobuf-net with async, gzip and less boilerplate.
Stars: ✭ 50 (-1.96%)
Mutual labels:  async
Rq
Simple job queues for Python
Stars: ✭ 8,065 (+15713.73%)
Mutual labels:  async
Vim Grepper
👾 Helps you win at grep.
Stars: ✭ 1,030 (+1919.61%)
Mutual labels:  async
Rackula
Generate a static site from any rack middleware.
Stars: ✭ 49 (-3.92%)
Mutual labels:  async
Caf
Cancelable Async Flows (CAF)
Stars: ✭ 1,027 (+1913.73%)
Mutual labels:  async

recloser

Crates.io Docs MIT licensed Rustc Version 1.36+

A concurrent circuit breaker implemented with ring buffers.

The Recloser struct provides a call(...) method to wrap function calls that may fail, it will eagerly reject them when some failure_rate is reached, and it will allow them again after some time. A future aware version of call(...) is also available through an AsyncRecloser wrapper.

The API is largely based on failsafe and the ring buffer implementation on resilient4j.

Usage

The Recloser can be in three states:

  • Closed(RingBuffer(len)): The initial Recloser's state. At least len calls will be performed before calculating a failure_rate based on which transitions to Open(_) state may happen.
  • Open(duration): All calls will return Err(Error::Rejected) until duration has elapsed, then transition to HalfOpen(_) state will happen.
  • HalfOpen(RingBuffer(len)): At least len calls will be performed before calculating a failure_rate based on which transitions to either Closed(_) or Open(_) states will happen.

The state transition settings can be customized as follows:

use std::time::Duration;
use recloser::Recloser;

// Equivalent to Recloser::default()
let recloser = Recloser::custom()
   .error_rate(0.5)
   .closed_len(100)
   .half_open_len(10)
   .open_wait(Duration::from_secs(30))
   .build();

Wrapping dangerous function calls in order to control failure propagation:

use recloser::{Recloser, Error};

// Performs 1 call before calculating failure_rate
let recloser = Recloser::custom().closed_len(1).build();

let f1 = || Err::<(), usize>(1);

// First call, just recorded as an error
let res = recloser.call(f1);
assert!(matches!(res, Err(Error::Inner(1))));

// Now also computes failure_rate, that is 100% here
// Will transition to State::Open afterward
let res = recloser.call(f1);
assert!(matches!(res, Err(Error::Inner(1))));

let f2 = || Err::<(), i64>(-1);

// All calls are rejected (while in State::Open)
let res = recloser.call(f2);
assert!(matches!(res, Err(Error::Rejected)));

It is also possible to discard some errors on a per call basis. This behavior is controlled by the ErrorPredicate<E>trait, which is already implemented for all Fn(&E) -> bool.

use recloser::{Recloser, Error};

let recloser = Recloser::default();

let f = || Err::<(), usize>(1);

// Custom predicate that doesn't consider usize values as errors
let p = |_: &usize| false;

// Will not record resulting Err(1) as an error
let res = recloser.call_with(p, f);
assert!(matches!(res, Err(Error::Inner(1))));

Wrapping functions that return Futures requires to use an AsyncRecloser that just wraps a regular Recloser.

use futures::future;
use recloser::{Recloser, Error, AsyncRecloser};

let recloser = AsyncRecloser::from(Recloser::default());

let future = future::lazy(|_| Err::<(), usize>(1));
let future = recloser.call(future);

Performances

Benchmarks for Recloser and failsafe::CircuitBreaker

  • Single threaded workload: same performances
  • Multi threaded workload: Recloser has 10x better performances
recloser_simple         time:   [355.17 us 358.67 us 362.52 us]
failsafe_simple         time:   [403.47 us 406.90 us 410.29 us]
recloser_concurrent     time:   [668.44 us 674.26 us 680.48 us]
failsafe_concurrent     time:   [11.523 ms 11.613 ms 11.694 ms]

These benchmarks were run on a Intel Core i7-6700HQ @ 8x 3.5GHz CPU.

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].