Compare commits
38 Commits
Author | SHA1 | Date | |
---|---|---|---|
c79ff2fde0 | |||
c29a84d15e | |||
01274c1364 | |||
9c3f2cb7f7 | |||
9489f1a5a8 | |||
f6aba7fac6 | |||
772366e267 | |||
1e08ee3dbb | |||
78f0c4057a | |||
cf5d5268f6 | |||
ce2479f6ca | |||
82d4699bca | |||
5ab7cae1fe | |||
f049750e4c | |||
0b5f19fc77 | |||
14eabdbe82 | |||
ea568449fe | |||
6ec3a6031e | |||
0f8fd2343e | |||
12c00941b5 | |||
72755f9cf1 | |||
ae0b8b703e | |||
3c3f638004 | |||
ea5287152c | |||
14371cdfd7 | |||
3a1b1673ef | |||
89cbae24d0 | |||
7c1b317d08 | |||
1fec4e3708 | |||
0eb24aa937 | |||
5c88cdd3e3 | |||
d51716893f | |||
ff350f9193 | |||
3d774f6d9c | |||
b78423377c | |||
1446f4c3cf | |||
8a80480d94 | |||
b7b2992730 |
64
CHANGELOG.md
64
CHANGELOG.md
@ -6,6 +6,70 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [0.7.2] - 2025-06-25
|
||||
|
||||
### Added
|
||||
- add wait
|
||||
- add conditional, allows adding or waiting for close
|
||||
|
||||
### Fixed
|
||||
- *(deps)* update rust crate async-trait to v0.1.86 (#28)
|
||||
- *(deps)* update rust crate rand to 0.9.0 (#27)
|
||||
- *(deps)* update rust crate thiserror to v2.0.11 (#26)
|
||||
- *(deps)* update all dependencies (#25)
|
||||
- *(deps)* update rust crate async-trait to v0.1.84 (#24)
|
||||
- *(deps)* update rust crate thiserror to v2.0.9 (#22)
|
||||
- *(deps)* update rust crate thiserror to v2.0.8 (#21)
|
||||
- *(deps)* update rust crate thiserror to v2.0.7 (#20)
|
||||
- *(deps)* update rust crate thiserror to v2.0.6 (#19)
|
||||
- *(deps)* update rust crate thiserror to v2.0.5 (#18)
|
||||
- *(deps)* update rust crate tokio-util to v0.7.13 (#17)
|
||||
|
||||
### Other
|
||||
- chore
|
||||
|
||||
- *(deps)* update all dependencies (#29)
|
||||
- *(deps)* update rust crate anyhow to v1.0.95 (#23)
|
||||
- *(deps)* update all dependencies (#16)
|
||||
- *(deps)* update rust crate tracing-subscriber to v0.3.19 (#15)
|
||||
- *(deps)* update rust crate tracing to v0.1.41 (#13)
|
||||
|
||||
## [0.7.1] - 2024-11-24
|
||||
|
||||
### Fixed
|
||||
- make sure to close on final
|
||||
|
||||
## [0.7.0] - 2024-11-24
|
||||
|
||||
### Added
|
||||
- actually bubble up errors
|
||||
|
||||
### Fixed
|
||||
- *(deps)* update rust crate thiserror to v2 (#9)
|
||||
|
||||
## [0.6.0] - 2024-11-23
|
||||
|
||||
### Added
|
||||
- adding test to make sure we can gracefully shutdown
|
||||
- make sure to close down properly
|
||||
|
||||
## [0.5.0] - 2024-11-19
|
||||
|
||||
### Added
|
||||
- update name
|
||||
- respect sigterm
|
||||
- include author
|
||||
- update with rename
|
||||
|
||||
### Docs
|
||||
- add examples
|
||||
|
||||
## [0.4.0] - 2024-08-07
|
||||
|
||||
### Added
|
||||
- add correction
|
||||
- add small docs
|
||||
|
||||
## [0.3.0] - 2024-08-07
|
||||
|
||||
### Added
|
||||
|
280
Cargo.lock
generated
280
Cargo.lock
generated
@ -1,21 +1,21 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.22.0"
|
||||
version = "0.24.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678"
|
||||
checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler"
|
||||
version = "1.0.2"
|
||||
name = "adler2"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||
checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
@ -28,15 +28,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.86"
|
||||
version = "1.0.97"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da"
|
||||
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.81"
|
||||
version = "0.1.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
||||
checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -45,23 +45,23 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.3.0"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0"
|
||||
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.73"
|
||||
version = "0.3.74"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a"
|
||||
checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -78,15 +78,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.7.1"
|
||||
version = "1.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8318a53db07bb3f8dca91a600466bdb3f2eaadeedfdbcf02e1accbad9271ba50"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26a5c3fd7bfa1ce3897a3a3501d362b2d87b7f2583ebcb4a949ec25911025cbc"
|
||||
checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@ -96,9 +90,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0"
|
||||
checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -111,9 +105,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78"
|
||||
checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
@ -121,15 +115,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d"
|
||||
checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d"
|
||||
checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
@ -138,15 +132,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1"
|
||||
checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6"
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -155,21 +149,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5"
|
||||
checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004"
|
||||
checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.30"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48"
|
||||
checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
@ -185,20 +179,21 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.15"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.13.3+wasi-0.2.2",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.29.0"
|
||||
version = "0.31.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd"
|
||||
checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f"
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
@ -214,9 +209,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.155"
|
||||
version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
@ -234,23 +229,6 @@ version = "0.4.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24"
|
||||
|
||||
[[package]]
|
||||
name = "mad"
|
||||
version = "0.2.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"futures",
|
||||
"futures-util",
|
||||
"rand",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracing-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "matchers"
|
||||
version = "0.1.0"
|
||||
@ -268,25 +246,42 @@ checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.7.4"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08"
|
||||
checksum = "e2d80299ef12ff69b16a84bb182e3b9df68b5a91574d3d4fa6e41b65deec4df1"
|
||||
dependencies = [
|
||||
"adler",
|
||||
"adler2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.1"
|
||||
version = "1.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
|
||||
checksum = "80e04d1dcff3aae0704555fe5fee3bcfaf3d1fdf8a7e521d5b9d2b42acb52cec"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notmad"
|
||||
version = "0.7.1"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-trait",
|
||||
"futures",
|
||||
"futures-util",
|
||||
"rand",
|
||||
"thiserror",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
"tracing-subscriber",
|
||||
"tracing-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nu-ansi-term"
|
||||
version = "0.46.0"
|
||||
@ -299,18 +294,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.36.3"
|
||||
version = "0.36.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27b64972346851a39438c60b341ebc01bba47464ae329e55cf343eb93964efd9"
|
||||
checksum = "aedf0a2d09c573ed1d8d85b30c119153926a2b36dce0ab28322c09a117a4683e"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.19.0"
|
||||
version = "1.20.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
|
||||
|
||||
[[package]]
|
||||
name = "overload"
|
||||
@ -343,9 +338,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.14"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
|
||||
checksum = "915a1e146535de9163f3987b8944ed8cf49a18bb0056bcebcdcece385cece4ff"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
@ -359,43 +354,43 @@ version = "0.2.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04"
|
||||
dependencies = [
|
||||
"zerocopy",
|
||||
"zerocopy 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.86"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
|
||||
checksum = "f139b0662de085916d1fb67d2b4169d1addddda1919e696f3252b740b629986e"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.36"
|
||||
version = "1.0.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
|
||||
checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.8.5"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand_chacha",
|
||||
"rand_core",
|
||||
"zerocopy 0.8.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_chacha"
|
||||
version = "0.3.1"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||
dependencies = [
|
||||
"ppv-lite86",
|
||||
"rand_core",
|
||||
@ -403,32 +398,33 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.6.4"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||
checksum = "b08f3c9802962f7e1b25113931d94f43ed9725bebc59db9d0c3e9a23b67e15ff"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"zerocopy 0.8.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.3"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
|
||||
checksum = "9b6dfecf2c74bce2466cabf93f6664d6998a69eb21e39f4207930065b27b771f"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.10.6"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4219d74c6b67a3654a9fbebc4b419e22126d13d2f3c4a07ee0cb61ff79a79619"
|
||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata 0.4.7",
|
||||
"regex-syntax 0.8.4",
|
||||
"regex-automata 0.4.9",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -442,13 +438,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.7"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax 0.8.4",
|
||||
"regex-syntax 0.8.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -459,9 +455,9 @@ checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
@ -520,9 +516,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.72"
|
||||
version = "2.0.87"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||
checksum = "25aa4ce346d03a6dcd68dd8b4010bcb74e54e62c90c573f394c46eae99aba32d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -531,18 +527,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.63"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.63"
|
||||
version = "2.0.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -561,9 +557,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.39.2"
|
||||
version = "1.43.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "daa4fb1bc778bd6f04cbfc4bb2d06a7396a8f299dc33ea1900cedaa316f467b1"
|
||||
checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
@ -579,9 +575,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.4.0"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -590,9 +586,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.11"
|
||||
version = "0.7.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9cf6b47b3771c49ac75ad09a6162f53ad4b8088b76ac60e8ec1455b31a189fe1"
|
||||
checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
@ -603,9 +599,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.40"
|
||||
version = "0.1.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
|
||||
checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
@ -615,9 +611,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.27"
|
||||
version = "0.1.28"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
||||
checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@ -626,9 +622,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
version = "0.1.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
|
||||
checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
@ -647,9 +643,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.18"
|
||||
version = "0.3.19"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
|
||||
checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
@ -686,9 +682,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.12"
|
||||
version = "1.0.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b"
|
||||
checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe"
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
@ -702,6 +698,15 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.13.3+wasi-0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@ -797,6 +802,15 @@ version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.35"
|
||||
@ -804,7 +818,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
"zerocopy-derive",
|
||||
"zerocopy-derive 0.7.35",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a367f292d93d4eab890745e75a778da40909cab4d6ff8173693812f79c4a2468"
|
||||
dependencies = [
|
||||
"zerocopy-derive 0.8.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -817,3 +840,14 @@ dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3931cb58c62c13adec22e38686b559c86a30565e16ad6e8510a337cedc611e1"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
@ -3,7 +3,7 @@ members = ["crates/*"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.3.0"
|
||||
version = "0.7.2"
|
||||
|
||||
[workspace.dependencies]
|
||||
mad = { path = "crates/mad" }
|
||||
|
@ -41,3 +41,11 @@ async fn main() -> anyhow::Result<()> {
|
||||
}
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
||||
Can be found (here)[crates/mad/examples]
|
||||
|
||||
- basic
|
||||
- fn
|
||||
- signals
|
||||
- error_log
|
||||
|
@ -1,15 +1,19 @@
|
||||
[package]
|
||||
name = "mad"
|
||||
name = "notmad"
|
||||
version.workspace = true
|
||||
edition = "2021"
|
||||
description = "notmad is a life-cycle manager for long running rust operations"
|
||||
license = "MIT"
|
||||
repository = "https://github.com/kjuulh/mad"
|
||||
authors = ["kjuulh"]
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
anyhow.workspace = true
|
||||
async-trait = "0.1.81"
|
||||
futures = "0.3.30"
|
||||
futures-util = "0.3.30"
|
||||
rand = "0.8.5"
|
||||
thiserror = "1.0.63"
|
||||
rand = "0.9.0"
|
||||
thiserror = "2.0.0"
|
||||
tokio.workspace = true
|
||||
tokio-util = "0.7.11"
|
||||
tracing.workspace = true
|
||||
|
@ -5,12 +5,12 @@ use tracing::Level;
|
||||
|
||||
struct WaitServer {}
|
||||
#[async_trait]
|
||||
impl mad::Component for WaitServer {
|
||||
impl notmad::Component for WaitServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("WaitServer".into())
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), mad::MadError> {
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
let millis_wait = rand::thread_rng().gen_range(500..3000);
|
||||
|
||||
tracing::debug!("waiting: {}ms", millis_wait);
|
||||
@ -28,7 +28,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
.with_max_level(Level::TRACE)
|
||||
.init();
|
||||
|
||||
mad::Mad::builder()
|
||||
notmad::Mad::builder()
|
||||
.add(WaitServer {})
|
||||
.add(WaitServer {})
|
||||
.add(WaitServer {})
|
||||
|
@ -5,12 +5,12 @@ use tracing::Level;
|
||||
|
||||
struct ErrorServer {}
|
||||
#[async_trait]
|
||||
impl mad::Component for ErrorServer {
|
||||
impl notmad::Component for ErrorServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("ErrorServer".into())
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), mad::MadError> {
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
let millis_wait = rand::thread_rng().gen_range(500..3000);
|
||||
|
||||
tracing::debug!("waiting: {}ms", millis_wait);
|
||||
@ -18,7 +18,7 @@ impl mad::Component for ErrorServer {
|
||||
// Simulates a server running for some time. Is normally supposed to be futures blocking indefinitely
|
||||
tokio::time::sleep(std::time::Duration::from_millis(millis_wait)).await;
|
||||
|
||||
Err(mad::MadError::Inner(anyhow::anyhow!("expected error")))
|
||||
Err(notmad::MadError::Inner(anyhow::anyhow!("expected error")))
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,7 +30,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
|
||||
// Do note that only the first server which returns an error is guaranteed to be handled. This is because if servers don't respect cancellation, they will be dropped
|
||||
|
||||
mad::Mad::builder()
|
||||
notmad::Mad::builder()
|
||||
.add(ErrorServer {})
|
||||
.add(ErrorServer {})
|
||||
.add(ErrorServer {})
|
||||
|
@ -5,12 +5,12 @@ use tracing::Level;
|
||||
|
||||
struct WaitServer {}
|
||||
#[async_trait]
|
||||
impl mad::Component for WaitServer {
|
||||
impl notmad::Component for WaitServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("WaitServer".into())
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), mad::MadError> {
|
||||
async fn run(&self, _cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
let millis_wait = rand::thread_rng().gen_range(500..3000);
|
||||
|
||||
tracing::debug!("waiting: {}ms", millis_wait);
|
||||
@ -28,9 +28,11 @@ async fn main() -> anyhow::Result<()> {
|
||||
.with_max_level(Level::TRACE)
|
||||
.init();
|
||||
|
||||
mad::Mad::builder()
|
||||
let item = "some item".to_string();
|
||||
|
||||
notmad::Mad::builder()
|
||||
.add(WaitServer {})
|
||||
.add_fn(|cancel| async move {
|
||||
.add_fn(|_cancel| async move {
|
||||
let millis_wait = 50;
|
||||
|
||||
tracing::debug!("waiting: {}ms", millis_wait);
|
||||
@ -40,6 +42,24 @@ async fn main() -> anyhow::Result<()> {
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.add_fn(move |_cancel| {
|
||||
// I am an actual closure
|
||||
|
||||
let item = item.clone();
|
||||
|
||||
async move {
|
||||
let _item = item;
|
||||
|
||||
let millis_wait = 50;
|
||||
|
||||
tracing::debug!("waiting: {}ms", millis_wait);
|
||||
|
||||
// Simulates a server running for some time. Is normally supposed to be futures blocking indefinitely
|
||||
tokio::time::sleep(std::time::Duration::from_millis(millis_wait)).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.run()
|
||||
.await?;
|
||||
|
||||
|
@ -5,12 +5,12 @@ use tracing::Level;
|
||||
|
||||
struct WaitServer {}
|
||||
#[async_trait]
|
||||
impl mad::Component for WaitServer {
|
||||
impl notmad::Component for WaitServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("WaitServer".into())
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), mad::MadError> {
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
let millis_wait = rand::thread_rng().gen_range(500..3000);
|
||||
|
||||
tracing::debug!("waiting: {}ms", millis_wait);
|
||||
@ -24,12 +24,12 @@ impl mad::Component for WaitServer {
|
||||
|
||||
struct RespectCancel {}
|
||||
#[async_trait]
|
||||
impl mad::Component for RespectCancel {
|
||||
impl notmad::Component for RespectCancel {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("RespectCancel".into())
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), mad::MadError> {
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
cancellation.cancelled().await;
|
||||
tracing::debug!("stopping because job is cancelled");
|
||||
|
||||
@ -39,12 +39,12 @@ impl mad::Component for RespectCancel {
|
||||
|
||||
struct NeverStopServer {}
|
||||
#[async_trait]
|
||||
impl mad::Component for NeverStopServer {
|
||||
impl notmad::Component for NeverStopServer {
|
||||
fn name(&self) -> Option<String> {
|
||||
Some("NeverStopServer".into())
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), mad::MadError> {
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
// Simulates a server running for some time. Is normally supposed to be futures blocking indefinitely
|
||||
tokio::time::sleep(std::time::Duration::from_millis(999999999)).await;
|
||||
|
||||
@ -58,7 +58,7 @@ async fn main() -> anyhow::Result<()> {
|
||||
.with_max_level(Level::TRACE)
|
||||
.init();
|
||||
|
||||
mad::Mad::builder()
|
||||
notmad::Mad::builder()
|
||||
.add(WaitServer {})
|
||||
.add(NeverStopServer {})
|
||||
.add(RespectCancel {})
|
||||
|
@ -1,9 +1,14 @@
|
||||
use futures::stream::FuturesUnordered;
|
||||
use futures_util::StreamExt;
|
||||
use std::{fmt::Display, sync::Arc};
|
||||
use tokio::signal::unix::{SignalKind, signal};
|
||||
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::waiter::Waiter;
|
||||
|
||||
mod waiter;
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum MadError {
|
||||
#[error("component failed: {0}")]
|
||||
@ -69,6 +74,23 @@ impl Mad {
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_conditional(&mut self, condition: bool, component: impl IntoComponent) -> &mut Self {
|
||||
if condition {
|
||||
self.components.push(component.into_component());
|
||||
} else {
|
||||
self.components
|
||||
.push(Waiter::new(component.into_component()).into_component())
|
||||
}
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_wait(&mut self) -> &mut Self {
|
||||
self.components.push(Waiter::default().into_component());
|
||||
|
||||
self
|
||||
}
|
||||
|
||||
pub fn add_fn<F, Fut>(&mut self, f: F) -> &mut Self
|
||||
where
|
||||
F: Fn(CancellationToken) -> Fut + Send + Sync + 'static,
|
||||
@ -94,11 +116,12 @@ impl Mad {
|
||||
|
||||
let close_result = self.close_components().await;
|
||||
|
||||
tracing::info!("mad is closed down");
|
||||
match (run_result, close_result) {
|
||||
(Err(run), Err(close)) => {
|
||||
return Err(MadError::AggregateError(AggregateError {
|
||||
errors: vec![run, close],
|
||||
}))
|
||||
}));
|
||||
}
|
||||
(Ok(_), Ok(_)) => {}
|
||||
(Ok(_), Err(close)) => return Err(close),
|
||||
@ -131,6 +154,7 @@ impl Mad {
|
||||
let mut channels = Vec::new();
|
||||
let cancellation_token = CancellationToken::new();
|
||||
let job_cancellation = CancellationToken::new();
|
||||
let job_done = CancellationToken::new();
|
||||
|
||||
for comp in &self.components {
|
||||
let comp = comp.clone();
|
||||
@ -152,18 +176,51 @@ impl Mad {
|
||||
res = comp.run(job_cancellation) => {
|
||||
error_tx.send(CompletionResult { res , name }).await
|
||||
}
|
||||
_ = tokio::signal::ctrl_c() => {
|
||||
error_tx.send(CompletionResult { res: Ok(()) , name }).await
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
tokio::spawn({
|
||||
let cancellation_token = cancellation_token;
|
||||
let job_done = job_done.child_token();
|
||||
|
||||
let wait_cancel = self.should_cancel;
|
||||
|
||||
async move {
|
||||
let should_cancel =
|
||||
|cancel: CancellationToken,
|
||||
global_cancel: CancellationToken,
|
||||
wait: Option<std::time::Duration>| async move {
|
||||
if let Some(cancel_wait) = wait {
|
||||
cancel.cancel();
|
||||
tokio::time::sleep(cancel_wait).await;
|
||||
global_cancel.cancel();
|
||||
}
|
||||
};
|
||||
|
||||
tokio::select! {
|
||||
_ = cancellation_token.cancelled() => {
|
||||
job_cancellation.cancel();
|
||||
}
|
||||
_ = job_done.cancelled() => {
|
||||
should_cancel(job_cancellation, cancellation_token, wait_cancel).await;
|
||||
}
|
||||
_ = tokio::signal::ctrl_c() => {
|
||||
should_cancel(job_cancellation, cancellation_token,wait_cancel).await;
|
||||
}
|
||||
_ = signal_unix_terminate() => {
|
||||
should_cancel(job_cancellation, cancellation_token, wait_cancel).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
let mut futures = FuturesUnordered::new();
|
||||
for channel in channels.iter_mut() {
|
||||
futures.push(channel.recv());
|
||||
}
|
||||
|
||||
let mut errors = Vec::new();
|
||||
while let Some(Some(msg)) = futures.next().await {
|
||||
match msg.res {
|
||||
Err(e) => {
|
||||
@ -172,21 +229,20 @@ impl Mad {
|
||||
component = msg.name,
|
||||
"component ran to completion with error"
|
||||
);
|
||||
errors.push(e);
|
||||
}
|
||||
Ok(_) => {
|
||||
tracing::debug!(component = msg.name, "component ran to completion");
|
||||
}
|
||||
}
|
||||
|
||||
job_cancellation.cancel();
|
||||
if let Some(cancel_wait) = self.should_cancel {
|
||||
tokio::time::sleep(cancel_wait).await;
|
||||
|
||||
cancellation_token.cancel();
|
||||
}
|
||||
job_done.cancel();
|
||||
}
|
||||
|
||||
tracing::debug!("ran components");
|
||||
if !errors.is_empty() {
|
||||
return Err(MadError::AggregateError(AggregateError { errors }));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -208,6 +264,11 @@ impl Mad {
|
||||
}
|
||||
}
|
||||
|
||||
async fn signal_unix_terminate() {
|
||||
let mut sigterm = signal(SignalKind::terminate()).expect("Failed to bind SIGTERM handler");
|
||||
sigterm.recv().await;
|
||||
}
|
||||
|
||||
#[async_trait::async_trait]
|
||||
pub trait Component {
|
||||
fn name(&self) -> Option<String> {
|
||||
|
48
crates/mad/src/waiter.rs
Normal file
48
crates/mad/src/waiter.rs
Normal file
@ -0,0 +1,48 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
|
||||
use crate::{Component, MadError};
|
||||
|
||||
pub struct DefaultWaiter {}
|
||||
#[async_trait]
|
||||
impl Component for DefaultWaiter {
|
||||
async fn run(&self, _cancellation_token: CancellationToken) -> Result<(), MadError> {
|
||||
panic!("should never be called");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Waiter {
|
||||
comp: Arc<dyn Component + Send + Sync + 'static>,
|
||||
}
|
||||
|
||||
impl Default for Waiter {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
comp: Arc::new(DefaultWaiter {}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Waiter {
|
||||
pub fn new(c: Arc<dyn Component + Send + Sync + 'static>) -> Self {
|
||||
Self { comp: c }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Component for Waiter {
|
||||
fn name(&self) -> Option<String> {
|
||||
match self.comp.name() {
|
||||
Some(name) => Some(format!("waiter/{name}")),
|
||||
None => Some("waiter".into()),
|
||||
}
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation_token: CancellationToken) -> Result<(), MadError> {
|
||||
cancellation_token.cancelled().await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use async_trait::async_trait;
|
||||
use mad::{Component, Mad};
|
||||
use notmad::{Component, Mad};
|
||||
use rand::Rng;
|
||||
use tokio::sync::Mutex;
|
||||
use tokio_util::sync::CancellationToken;
|
||||
use tracing_test::traced_test;
|
||||
|
||||
@ -12,7 +15,7 @@ impl Component for NeverEndingRun {
|
||||
Some("NeverEndingRun".into())
|
||||
}
|
||||
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), mad::MadError> {
|
||||
async fn run(&self, cancellation: CancellationToken) -> Result<(), notmad::MadError> {
|
||||
let millis_wait = rand::thread_rng().gen_range(50..1000);
|
||||
|
||||
tokio::time::sleep(std::time::Duration::from_millis(millis_wait)).await;
|
||||
@ -86,3 +89,51 @@ async fn test_can_run_components() -> anyhow::Result<()> {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
#[traced_test]
|
||||
async fn test_can_shutdown_gracefully() -> anyhow::Result<()> {
|
||||
let check = Arc::new(Mutex::new(None));
|
||||
|
||||
Mad::builder()
|
||||
.add_fn({
|
||||
let check = check.clone();
|
||||
|
||||
move |cancel| {
|
||||
let check = check.clone();
|
||||
|
||||
async move {
|
||||
let start = std::time::SystemTime::now();
|
||||
tracing::info!("waiting for cancel");
|
||||
cancel.cancelled().await;
|
||||
tracing::info!("submitting check");
|
||||
let mut check = check.lock().await;
|
||||
let elapsed = start.elapsed().expect("to be able to get elapsed");
|
||||
*check = Some(elapsed);
|
||||
tracing::info!("check submitted");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
})
|
||||
.add_fn(|_| async move {
|
||||
tracing::info!("starting sleep");
|
||||
tokio::time::sleep(std::time::Duration::from_millis(100)).await;
|
||||
tracing::info!("sleep ended");
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.run()
|
||||
.await?;
|
||||
|
||||
let check = check
|
||||
.lock()
|
||||
.await
|
||||
.expect("to be able to get a duration from cancel");
|
||||
|
||||
// We default wait 100 ms for graceful shutdown, and we explicitly wait 100ms in the sleep routine
|
||||
tracing::info!("check millis: {}", check.as_millis());
|
||||
assert!(check.as_millis() < 250);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
3
renovate.json
Normal file
3
renovate.json
Normal file
@ -0,0 +1,3 @@
|
||||
{
|
||||
"$schema": "https://docs.renovatebot.com/renovate-schema.json"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user