[−][src]Crate slottle
A throttle pool library designed for thread-based concurrency.
Concepts
This crate contain two primary types: ThrottlePool
and Throttle
.
Each Throttle
has it own concurrent and interval state for delaying.
On the other hand, ThrottlePool
can automatic create Throttle
when
corresponding id
first time be used. User can treat id
as some kind of
resource identity like hostname, IP address, etc.
Here is a running chart of a ThrottlePool
with concurrent
== 2
.
ThrottlePool
|
+-- Throttle (resource-1)
| |
| +-- Thread quota 1 ... run ...
| +-- Thread quota 2 ... run ...
|
+-- Throttle (resource-2)
| |
| +-- Thread quota 3 ... run ...
| +-- Thread quota 4 ... run ...
...
+-- Throttle (resource-N)
|
+-- Thread quota 2N-1 ... run ...
+-- Thread quota 2N ... run ...
If concurrent == 1
, thread quota usage may work like this:
f: assigned jobs, s: sleep function
thread 1: |f()----|s()----|f()--|s()------|f()----------------|f()-----|..........|f()--
| interval | interval | interval |...| interval |...|
^^^^^^^^^^^^^^^^^^^^^
job run longer than interval --^ ^^^^^^^^
so skip sleep() step /
/
If new job not inject into the -----------------------
"should wait interval", sleep() will not be triggered
time pass ----->
If concurrent == 2
, threads will work like this:
f: assigned jobs, s: sleep function
thread 1: |f()----|s()----|f()--|s()------|f()------------------------------|.|f()--
| interval | interval | 2x interval |...|
thread 2: |f()-|s()-------|f()-------|s()-|f()-|s()-------|f()|s()|f()---s|f()------
| interval | interval | interval | 1/2 | 1/2 |
^^^^^^^^^^^^^^^^^
max concurrent forced to 2 ---------------^
but expected value of maximux access speed is "concurrent per interval".
time pass ----->
Throttle
would not create threads, but only block current thread.
User should create threads by themself and sync throttle to all those
threads, to control access speed entirely.
User can just using Throttle
directly if not need the pool-related facility.
Examples
use std::time::Duration; use slottle::ThrottlePool; use rayon::prelude::*; // Create ThrottlePool to store some state. // // In here `id` is `bool` type for demonstration. If you're writing // a web spider, type of `id` might be `url::Host`. let throttles: ThrottlePool<bool> = ThrottlePool::builder() .interval(Duration::from_millis(1)) // set interval to 1 ms .concurrent(2) // 2 concurrent for each throttle .build() .unwrap(); // make sure you have enough of threads. For example: rayon::ThreadPoolBuilder::new().num_threads(8).build_global().unwrap(); let results: Vec<i32> = vec![1, 2, 3, 4, 5] .into_par_iter() // run parallel .map(|x| throttles.run( x == 5, // 5 in throttle `true`, 1,2,3,4 in throttle `false` || {x + 1}, // here is the operation should be throttled )) .collect(); assert_eq!(results, vec![2, 3, 4, 5, 6,]);
Features
fuzzy_fns
: (default) Offer a helper function can fuzzing theinterval
in all operations.retrying
: (optional, experimental) Addrun_retry(...)
APIs to support [retry] beside the standard throttle operation.
Other
Crate name slottle
is an abbr of "slotted throttle". Which is the original name of current ThrottlePool
.
Modules
fuzzy_fns | Helper functions can assign into |
Structs
Throttle | Limiting resource access speed by interval and concurrent. |
ThrottleBuilder | Use it to build a |
ThrottlePool | A |
ThrottlePoolBuilder | Use it to build a |