Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
079a034
implement retry queues as per-thread
jdidion Feb 4, 2025
4b8f7c2
WIP
jdidion Feb 4, 2025
811eef8
WIP
jdidion Feb 4, 2025
38d4138
refactor
jdidion Feb 7, 2025
b427c72
implement non-locking outcome store
jdidion Feb 7, 2025
57a54ad
fix lints
jdidion Feb 8, 2025
d4c8977
WIP
jdidion Feb 11, 2025
88e366f
WIP
jdidion Feb 11, 2025
234c2ea
reorganize hive module
jdidion Feb 16, 2025
6e6d97c
reorganize hive module
jdidion Feb 16, 2025
6e57c6a
cleanup
jdidion Feb 19, 2025
d715e0a
refactor; finish workstealing queue impl
jdidion Feb 19, 2025
5edcab0
fix lints
jdidion Feb 19, 2025
931393f
add workstealing builder
jdidion Feb 19, 2025
f5e7901
fix tests
jdidion Feb 20, 2025
2ec4015
add missing files
jdidion Feb 20, 2025
5671c45
fix formatting
jdidion Feb 20, 2025
dfa184c
fix
jdidion Feb 20, 2025
887dd6f
fix test
jdidion Feb 20, 2025
3680160
cleanup
jdidion Feb 20, 2025
13f6ce2
fix
jdidion Feb 20, 2025
3ac8020
fix import order
jdidion Feb 20, 2025
022fb1b
update docs
jdidion Feb 20, 2025
a2313b5
refactor queue builders into trait, provide builder functions
jdidion Feb 20, 2025
a23eeb2
add queue
jdidion Feb 20, 2025
8d09eef
fix
jdidion Feb 20, 2025
81d1ff3
fix
jdidion Feb 20, 2025
2a1d472
fix doc tests
jdidion Feb 21, 2025
5e970d1
update to rust 2024/1.85
jdidion Feb 22, 2025
59ea7f0
fix test
jdidion Feb 22, 2025
8f79aa3
add workstealng tests
jdidion Feb 22, 2025
5c9e5c8
fix workflow
jdidion Feb 22, 2025
44349f3
update fmt
jdidion Feb 22, 2025
f379092
remove captures that are no longer necessary w rust 2024
jdidion Feb 22, 2025
2e586fa
fix tests
jdidion Feb 23, 2025
9c4b082
fix tests
jdidion Feb 23, 2025
658cd31
fix tests
jdidion Feb 23, 2025
d3ec064
fix tests
jdidion Feb 23, 2025
2f0a57b
fix tests
jdidion Feb 23, 2025
ff9fce6
add tests
jdidion Feb 24, 2025
551cd9d
fix
jdidion Feb 24, 2025
6551f47
add mock module; add support for task weighting
jdidion Feb 27, 2025
0b76afa
move mock
jdidion Feb 27, 2025
b170dd7
add test
jdidion Mar 4, 2025
d180c2b
add tests
jdidion Mar 12, 2025
1b128f4
fix lints
jdidion Mar 12, 2025
a9d7416
add tests
jdidion Mar 14, 2025
d4d68d4
replace rand w nanorand
jdidion Mar 14, 2025
02257e0
allow paste dep
jdidion Mar 14, 2025
6965c02
fix test
jdidion Mar 14, 2025
eafd0d2
allow paste dep
jdidion Mar 14, 2025
fa89d06
fix lints
jdidion Mar 14, 2025
ad83948
fix lints
jdidion Mar 14, 2025
f710176
fix doc tests
jdidion Mar 14, 2025
4b17175
fix doc tests
jdidion Mar 14, 2025
b720787
fix
jdidion Mar 14, 2025
ade5e53
fix
jdidion Mar 14, 2025
f258782
add debugging
jdidion Mar 14, 2025
c9bee11
fix test
jdidion Mar 14, 2025
92928a5
fix test
jdidion Mar 14, 2025
cdcec29
use backoff rather than park
jdidion Mar 14, 2025
5b71f83
fix doc issues
jdidion Mar 17, 2025
e6bde1a
update/fix docs
jdidion Mar 17, 2025
b2d0519
add diagram
jdidion Mar 17, 2025
674ca53
combine weighted iterator extension traits
jdidion Mar 17, 2025
5d6df2e
combine weighted iterator extension traits
jdidion Mar 17, 2025
a20361f
update changelog
jdidion Mar 17, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,27 +14,28 @@ jobs:
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/cargo-deny-action@v2
with:
rust-version: "1.85.0"
- uses: actions-rust-lang/setup-rust-toolchain@v1
with:
components: rustfmt, clippy
- run: |
cargo clippy --all-targets -F affinity,batching,retry \
cargo clippy --all-targets -F affinity,local-batch,retry \
-- -D warnings $(cat .lints | cut -f1 -d"#" | tr '\n' ' ')
- run: cargo fmt -- --check
- run: cargo doc -F affinity,batching,retry
- run: cargo test -F affinity,batching,retry --doc
- run: RUSTDOCFLAGS="-D warnings" cargo doc -F affinity,local-batch,retry
- run: cargo test -F affinity,local-batch,retry --doc

coverage:
name: Code coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/cargo-deny-action@v2
- uses: actions-rust-lang/setup-rust-toolchain@v1
- name: Install cargo-llvm-cov
uses: taiki-e/install-action@cargo-llvm-cov
- name: Generate code coverage
run: cargo llvm-cov --lcov --output-path lcov.info -F affinity,batching,retry
run: cargo llvm-cov --lcov --output-path lcov.info -F affinity,local-batch,retry
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v3
with:
Expand All @@ -58,7 +59,6 @@ jobs:
- loole
steps:
- uses: actions/checkout@v4
- uses: EmbarkStudios/cargo-deny-action@v2
- uses: actions-rust-lang/setup-rust-toolchain@v1
- uses: actions-rs/cargo@v1
with:
Expand Down
30 changes: 29 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,36 @@

## 0.3.0

The general theme of this release is performance improvement by eliminating thread contention due to unnecessary locking of shared state. This required making some breaking changes to the API.

* **Breaking**
* `beekeeper::hive::Hive` type signature has changed
* Removed the `W: Worker` parameter as it is redundant (can be obtained from `Q::Kind`)
* Added `T: TaskQueues`to specify the `TaskQueues` implementation
* The `Builder` interface has been re-written to enable maximum flexibility.
* `Builder` is now a trait that must be in scope.
* `ChannelBuilder` implements the previous builder functionality.
* `OpenBuilder` has no type parameters and can be specialized to create a `Hive` with any combination of `Queen` and `TaskQueues`.
* `BeeBuilder` and `FullBuilder` are intermediate types that generally should not be instantiated directly.
* `beekeeper::bee::Queen::create` now takes `&self` rather than `&mut self`. There is a new type, `beekeeper::bee::QueenMut`, with a `create(&mut self)` method, and needs to be wrapped in a `beekeeper::bee::QueenCell` to implement the `Queen` trait. This enables the `Hive` to create new workers without locking in the case of a `Queen` that does not need mutable state.
* `beekeeper::bee::Context` now takes a generic parameter that must be input type of the `Worker`.
* `beekeeper::hive::Hive::try_into_husk` now has an `urgent` parameter to indicate whether queued tasks should be abandoned when shutting down the hive (`true`) or if they should be allowed to finish processing (`false`).
* The type of `attempt` and `max_retries` has been changed to `u8`. This reduces memory usage and should still allow for the majority of use cases.
* The `::of` methods have been removed from stock `Worker`s in favor of implementing `From`.
* Features
* Added the `batching` feature, which enables worker threads to queue up batches of tasks locally, which can alleviate contention between threads in the pool, especially when there are many short-lived tasks.
* Added the `TaskQueues` trait, which enables `Hive` to be specialized for different implementations of global (i.e., sending tasks from the `Hive` to worker threads) and local (i.e., worker thread-specific) queues.
* `ChannelTaskQueues` implements the existing behavior, using a channel for sending tasks.
* `WorkstealingTaskQueues` has been added to implement the workstealing pattern, based on `crossbeam::dequeue`.
* Added the `local-batch` feature, which enables worker threads to queue up batches of tasks locally, which can alleviate contention between threads in the pool, especially when there are many short-lived tasks.
* When this feature is enabled, tasks can be optionally weighted (by wrapping each input in `crate::hive::Weighted`) to help evenly distribute tasks with variable processing times.
* Enabling this feature should be transparent (i.e., not break existing code), and the `Hive`'s task submission methods support both weighted and unweighted inputs (due to the blanket implementation of `From<T> for Weighted<T>`); however, there are some cases where it is now necessary to specify the input type where before it could be elided.
* Added the `Context::submit` method, which enables tasks to submit new tasks to the `Hive`.
* Other
* Switched to using thread-local retry queues for the implementation of the `retry` feature, to reduce thread-contention.
* Switched to storing `Outcome`s in the hive using a data structure that does not require locking when inserting, which should reduce thread contention when using `*_store` operations.
* Switched to using `crossbeam_channel` for the task input channel in `ChannelTaskQueues`. These are multi-produer, multi-consumer channels (mpmc; as opposed to `std::mpsc`, which is single-consumer), which means it is no longer necessary for worker threads to aquire a Mutex lock on the channel receiver when getting tasks.
* Added the `beekeeper::hive::mock` module, which has a `MockTaskRunner` for `apply`ing a worker in a mock context. This is useful for testing your `Worker`.
* Updated to `2024` edition and Rust version `1.85`

## 0.2.1

Expand Down
36 changes: 25 additions & 11 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,51 +2,65 @@
name = "beekeeper"
description = "A full-featured worker pool library for parallelizing tasks"
version = "0.3.0"
edition = "2021"
rust-version = "1.80"
edition = "2024"
rust-version = "1.85"
authors = ["John Didion <github@didion.net>"]
repository = "https://github.com/jdidion/beekeeper"
license = "MIT OR Apache-2.0"

[dependencies]
crossbeam-channel = "0.5.13"
crossbeam-deque = "0.8.6"
crossbeam-queue = "0.3.12"
crossbeam-utils = "0.8.20"
derive_more = { version = "2.0.1", features = ["debug"] }
nanorand = { version = "0.7.0", default-features = false, features = [
"std",
"tls",
] }
num = "0.4.3"
num_cpus = "1.16.0"
parking_lot = "0.12.3"
paste = "1.0.15"
simple-mermaid = "0.2.0"
thiserror = "1.0.63"
# required with the `affinity` feature
core_affinity = { version = "0.8.1", optional = true }
# required with the `batching` feature
crossbeam-queue = { version = "0.3.12", optional = true }
# alternate channel implementations that can be enabled with features
crossbeam-channel = { version = "0.5.13", optional = true }
# required with alternate outcome channel implementations that can be enabled with features
# NOTE: these version requirements could be relaxed as we don't actually depend on the
# functionality of these crates internally (other than in tests)
flume = { version = "0.11.1", optional = true }
loole = { version = "0.4.0", optional = true }

[dev-dependencies]
divan = "0.1.17"
itertools = "0.14.0"
serial_test = "3.2.0"
#rstest = "0.22.0"
rstest = "0.22.0"
stacker = "0.1.17"
aquamarine = "0.6.0"
simple-mermaid = "0.2.0"

[[bench]]
name = "perf"
harness = false

[features]
default = []
default = ["local-batch"]
affinity = ["dep:core_affinity"]
batching = ["dep:crossbeam-queue"]
local-batch = []
retry = []
crossbeam = ["dep:crossbeam-channel"]
crossbeam = []
flume = ["dep:flume"]
loole = ["dep:loole"]

[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = [
'cfg(coverage,coverage_nightly)',
] }

[package.metadata.cargo-all-features]
allowlist = ["affinity", "batching", "retry"]
allowlist = ["affinity", "local-batch", "retry"]

[profile.release]
lto = true
Expand Down
Loading