recloser
所属分类:硬件设计
开发工具:Rust
文件大小:0KB
下载次数:0
上传日期:2023-06-14 09:26:09
上 传 者:
sh-1993
说明: 用环形缓冲器实现的并发断路器,
(A concurrent circuit breaker implemented with ring buffers,)
文件列表:
Cargo.toml (520, 2023-06-14)
LICENSE (1070, 2023-06-14)
benches/ (0, 2023-06-14)
benches/recloser.rs (2709, 2023-06-14)
src/ (0, 2023-06-14)
src/async.rs (4414, 2023-06-14)
src/error.rs (767, 2023-06-14)
src/lib.rs (358, 2023-06-14)
src/recloser.rs (9997, 2023-06-14)
src/ring_buffer.rs (2995, 2023-06-14)
# recloser [![latest]][crates.io] [![doc]][docs.rs]
[latest]: https://img.shields.io/crates/v/recloser.svg
[crates.io]: https://crates.io/crates/recloser
[doc]: https://docs.rs/recloser/badge.svg
[docs.rs]: https://docs.rs/recloser
A concurrent [circuit breaker][cb] 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][].
[cb]: https://martinfowler.com/bliki/CircuitBreaker.html
[failsafe]: https://github.com/dmexe/failsafe-rs
[resilient4j]: https://resilience4j.readme.io/docs/circuitbreaker
## Usage
The `Recloser` can be in three states:
- `State::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 `State::Open(_)` state may happen.
- `State::Open(duration)`: All calls will return `Err(Error::Rejected)` until
`duration` has elapsed, then transition to `State::HalfOpen(_)` state will happen.
- `State::HalfOpen(RingBuffer(len))`: At least `len` calls will be performed before
calculating a `failure_rate` based on which transitions to either `State::Closed(_)`
or `State::Open(_)` states will happen.
The state transition settings can be customized as follows:
```rust
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:
```rust
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`trait, which is already
implemented for all `Fn(&E) -> bool`.
```rust
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 `Future`s requires to use an `AsyncRecloser` that just
wraps a regular `Recloser`.
```rust
use std::future;
use recloser::{Recloser, Error, AsyncRecloser};
let recloser = AsyncRecloser::from(Recloser::default());
let future = future::ready::>(Err(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
```sh
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.
近期下载者:
相关文件:
收藏者: