From afeff00273d105959472d86a0ccc71b8797ecc7c Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 6 Oct 2025 23:40:03 +0800 Subject: [PATCH 1/3] refactor: rework Fastimer API Signed-off-by: tison --- Cargo.lock | 412 +++++++++++++------ Cargo.toml | 26 +- fastimer-core/Cargo.toml | 21 + {fastimer-driver => fastimer-core}/README.md | 14 +- fastimer-core/src/lib.rs | 46 +++ fastimer-driver/Cargo.toml | 42 -- fastimer-driver/src/heap.rs | 105 ----- fastimer-driver/src/lib.rs | 159 ------- fastimer-driver/tests/integration.rs | 58 --- fastimer-tokio/Cargo.toml | 10 +- fastimer-tokio/README.md | 4 +- fastimer-tokio/src/lib.rs | 14 +- fastimer/Cargo.toml | 14 +- fastimer/src/lib.rs | 52 +-- fastimer/src/schedule/arbitrary.rs | 2 +- fastimer/src/schedule/notify.rs | 2 +- fastimer/src/schedule/simple.rs | 2 +- fastimer/tests/common/mod.rs | 43 -- fastimer/tests/interval.rs | 9 +- fastimer/tests/schedule.rs | 34 +- xtask/Cargo.toml | 4 +- xtask/src/main.rs | 2 + 22 files changed, 446 insertions(+), 629 deletions(-) create mode 100644 fastimer-core/Cargo.toml rename {fastimer-driver => fastimer-core}/README.md (68%) create mode 100644 fastimer-core/src/lib.rs delete mode 100644 fastimer-driver/Cargo.toml delete mode 100644 fastimer-driver/src/heap.rs delete mode 100644 fastimer-driver/src/lib.rs delete mode 100644 fastimer-driver/tests/integration.rs delete mode 100644 fastimer/tests/common/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 36a022a..4697a02 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,15 +17,6 @@ version = "2.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" -[[package]] -name = "aho-corasick" -version = "1.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" -dependencies = [ - "memchr", -] - [[package]] name = "anstream" version = "0.6.18" @@ -81,12 +72,6 @@ version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" -[[package]] -name = "atomic-waker" -version = "1.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" - [[package]] name = "autocfg" version = "1.4.0" @@ -182,34 +167,20 @@ dependencies = [ ] [[package]] -name = "crossbeam-queue" -version = "0.3.12" +name = "env_home" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f58bbc28f91df819d0aa2a2c00cd19754769c2fad90579b3592b1c9ba7a3115" -dependencies = [ - "crossbeam-utils", -] +checksum = "c7f84e12ccf0a7ddc17a6c41c93326024c42920d7ee630d04950e6926645c0fe" [[package]] -name = "crossbeam-utils" -version = "0.8.21" +name = "erased-serde" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" - -[[package]] -name = "either" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" - -[[package]] -name = "env_filter" -version = "0.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "186e05a59d4c50738528153b83b0b0194d3a29507dfec16eccd4b342903397d0" +checksum = "259d404d09818dec19332e31d94558aeb442fea04c817006456c24b5460bbd4b" dependencies = [ - "log", - "regex", + "serde", + "serde_core", + "typeid", ] [[package]] @@ -224,8 +195,10 @@ dependencies = [ [[package]] name = "fastimer" -version = "0.9.0" +version = "0.9.1" dependencies = [ + "fastimer-core", + "fastimer-tokio", "log", "logforth", "pin-project", @@ -233,21 +206,14 @@ dependencies = [ ] [[package]] -name = "fastimer-driver" -version = "0.9.0" -dependencies = [ - "atomic-waker", - "crossbeam-queue", - "fastimer", - "parking", - "tokio", -] +name = "fastimer-core" +version = "0.1.0" [[package]] name = "fastimer-tokio" -version = "0.9.0" +version = "0.10.0" dependencies = [ - "fastimer", + "fastimer-core", "tokio", ] @@ -264,12 +230,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] -name = "home" -version = "0.5.9" +name = "io-uring" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3d1354bf6b7235cb4a0576c2619fd4ed18183f689b12b006a0ee7329eeff9a5" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "windows-sys 0.52.0", + "bitflags", + "cfg-if", + "libc", ] [[package]] @@ -278,6 +246,12 @@ version = "1.70.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + [[package]] name = "jiff" version = "0.2.8" @@ -321,15 +295,15 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.169" +version = "0.2.176" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" +checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174" [[package]] name = "linux-raw-sys" -version = "0.4.14" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" [[package]] name = "lock_api" @@ -343,21 +317,79 @@ dependencies = [ [[package]] name = "log" -version = "0.4.27" +version = "0.4.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" +checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +dependencies = [ + "sval", + "sval_ref", + "value-bag", +] [[package]] name = "logforth" -version = "0.24.0" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd048889d633cac5c189eca703f5c5ed65210d358eb5910a478e233d42528d6e" +dependencies = [ + "logforth-append-file", + "logforth-bridge-log", + "logforth-core", + "logforth-layout-json", + "logforth-layout-text", +] + +[[package]] +name = "logforth-append-file" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aeb66a16ac0f5cdd6a0e7005c6e1fa2744e915244941ac6cd01bd56de2995f48" +dependencies = [ + "jiff", + "logforth-core", +] + +[[package]] +name = "logforth-bridge-log" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "392ff9723d68a943ccffabe03b5272f7c93104f0008a6c7357ef888c21ab6297" +dependencies = [ + "log", + "logforth-core", +] + +[[package]] +name = "logforth-core" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7d12336d4771854b6fdbf75bab8257e62d4221d1f9d7187fc254b29aa3bd23b" +checksum = "7666819ed32e38aabb45959a632b0f9c25fc77e60c824b02a5fcd87ab626f6ed" dependencies = [ "anyhow", + "value-bag", +] + +[[package]] +name = "logforth-layout-json" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49e1db5d0f5b1bc57134ff9d1ed3889910d230545f3d249bde44bac0e8a8724f" +dependencies = [ + "jiff", + "logforth-core", + "serde", + "serde_json", +] + +[[package]] +name = "logforth-layout-text" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c00c67d92539b26edbba5e43ce8f5b97d62412c1cfc9463400f50cfad2f1f1bf" +dependencies = [ "colored", - "env_filter", "jiff", - "log", + "logforth-core", ] [[package]] @@ -395,12 +427,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "parking" -version = "2.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" - [[package]] name = "parking_lot" version = "0.12.3" @@ -426,18 +452,18 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.9" +version = "1.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", @@ -492,35 +518,6 @@ dependencies = [ "bitflags", ] -[[package]] -name = "regex" -version = "1.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" -dependencies = [ - "aho-corasick", - "memchr", - "regex-automata", - "regex-syntax", -] - -[[package]] -name = "regex-automata" -version = "0.4.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" -dependencies = [ - "aho-corasick", - "memchr", - "regex-syntax", -] - -[[package]] -name = "regex-syntax" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" - [[package]] name = "rustc-demangle" version = "0.1.24" @@ -529,17 +526,23 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.41" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7f649912bc1495e167a6edee79151c84b1bad49748cb4f1f1167f459f6224f6" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" dependencies = [ "bitflags", "errno", "libc", "linux-raw-sys", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + [[package]] name = "scopeguard" version = "1.2.0" @@ -548,24 +551,65 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_buf" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a86be9d6c7d34718d2ec6f56c8d6a4671d1a7357c2a6921f47fe5a3ee6056cc" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.219" +version = "1.0.228" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" dependencies = [ "proc-macro2", "quote", "syn", ] +[[package]] +name = "serde_fmt" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d4ddca14104cd60529e8c7f7ba71a2c8acd8f7f5cfcdc2faf97eeb7c3010a4" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + [[package]] name = "signal-hook-registry" version = "1.4.2" @@ -575,6 +619,12 @@ dependencies = [ "libc", ] +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + [[package]] name = "smallvec" version = "1.13.2" @@ -583,12 +633,12 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" -version = "0.5.8" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c970269d99b64e60ec3bd6ad27270092a5394c4e309314b18ae3fe575695fbe8" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" dependencies = [ "libc", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -597,6 +647,84 @@ version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" +[[package]] +name = "sval" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d94c4464e595f0284970fd9c7e9013804d035d4a61ab74b113242c874c05814d" + +[[package]] +name = "sval_buffer" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0f46e34b20a39e6a2bf02b926983149b3af6609fd1ee8a6e63f6f340f3e2164" +dependencies = [ + "sval", + "sval_ref", +] + +[[package]] +name = "sval_dynamic" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03d0970e53c92ab5381d3b2db1828da8af945954d4234225f6dd9c3afbcef3f5" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_fmt" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43e5e6e1613e1e7fc2e1a9fdd709622e54c122ceb067a60d170d75efd491a839" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_json" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aec382f7bfa6e367b23c9611f129b94eb7daaf3d8fae45a8d0a0211eb4d4c8e6" +dependencies = [ + "itoa", + "ryu", + "sval", +] + +[[package]] +name = "sval_nested" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3049d0f99ce6297f8f7d9953b35a0103b7584d8f638de40e64edb7105fa578ae" +dependencies = [ + "sval", + "sval_buffer", + "sval_ref", +] + +[[package]] +name = "sval_ref" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f88913e77506085c0a8bf6912bb6558591a960faf5317df6c1d9b227224ca6e1" +dependencies = [ + "sval", +] + +[[package]] +name = "sval_serde" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f579fd7254f4be6cd7b450034f856b78523404655848789c451bacc6aa8b387d" +dependencies = [ + "serde_core", + "sval", + "sval_nested", +] + [[package]] name = "syn" version = "2.0.100" @@ -610,20 +738,22 @@ dependencies = [ [[package]] name = "tokio" -version = "1.43.0" +version = "1.47.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", "parking_lot", "pin-project-lite", "signal-hook-registry", + "slab", "socket2", "tokio-macros", - "windows-sys 0.52.0", + "windows-sys 0.59.0", ] [[package]] @@ -637,6 +767,12 @@ dependencies = [ "syn", ] +[[package]] +name = "typeid" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c" + [[package]] name = "unicode-ident" version = "1.0.14" @@ -649,6 +785,43 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" +[[package]] +name = "value-bag" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "943ce29a8a743eb10d6082545d861b24f9d1b160b7d741e0f2cdf726bec909c5" +dependencies = [ + "value-bag-serde1", + "value-bag-sval2", +] + +[[package]] +name = "value-bag-serde1" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35540706617d373b118d550d41f5dfe0b78a0c195dc13c6815e92e2638432306" +dependencies = [ + "erased-serde", + "serde", + "serde_buf", + "serde_fmt", +] + +[[package]] +name = "value-bag-sval2" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6fe7e140a2658cc16f7ee7a86e413e803fc8f9b5127adc8755c19f9fefa63a52" +dependencies = [ + "sval", + "sval_buffer", + "sval_dynamic", + "sval_fmt", + "sval_json", + "sval_ref", + "sval_serde", +] + [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -657,12 +830,11 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "which" -version = "7.0.0" +version = "8.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9cad3279ade7346b96e38731a641d7343dd6a53d55083dd54eadfa5a1b38c6b" +checksum = "d3fabb953106c3c8eea8306e4393700d7657561cb43122571b172bbfb7c7ba1d" dependencies = [ - "either", - "home", + "env_home", "rustix", "winsafe", ] diff --git a/Cargo.toml b/Cargo.toml index 055d56c..b50064f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,30 +13,40 @@ # limitations under the License. [workspace] -members = ["fastimer", "fastimer-driver", "fastimer-tokio", "xtask"] +members = ["fastimer", "fastimer-core", "fastimer-tokio", "xtask"] resolver = "2" [workspace.package] edition = "2024" homepage = "https://github.com/fast/fastimer" license = "Apache-2.0" -readme = "README.md" repository = "https://github.com/fast/fastimer" +readme = "README.md" rust-version = "1.85.0" -version = "0.9.0" [workspace.dependencies] -fastimer = { version = "0.9.0", path = "fastimer" } -tokio = { version = "1.43.0" } +# Workspace dependencies +fastimer-core = { version = "0.1.0", path = "fastimer-core" } +fastimer-tokio = { version = "0.10.0", path = "fastimer-tokio" } + +# Crates.io dependencies +clap = { version = "4.5.20", features = ["derive"] } +log = { version = "0.4.28" } +logforth = { version = "0.28.1" } +pin-project = { version = "1.1.10" } +tokio = { version = "1.47.1" } +which = { version = "8.0.0" } [workspace.lints.rust] +missing_docs = "deny" unknown_lints = "deny" +unused_must_use = "deny" [workspace.lints.clippy] dbg_macro = "deny" [workspace.metadata.release] -pre-release-commit-message = "chore: release v{{version}}" -shared-version = true +pre-release-commit-message = "chore: Release {{crate_name}} version {{version}}" +sign-commit = true sign-tag = true -tag-name = "v{{version}}" +tag-message = "chore: Release {{crate_name}} version {{version}}" diff --git a/fastimer-core/Cargo.toml b/fastimer-core/Cargo.toml new file mode 100644 index 0000000..11f48b9 --- /dev/null +++ b/fastimer-core/Cargo.toml @@ -0,0 +1,21 @@ +[package] +name = "fastimer-core" +version = "0.1.0" + +description = "Core timer traits, types, and utilities for fastimer" +readme = "README.md" + +edition.workspace = true +homepage.workspace = true +license.workspace = true +repository.workspace = true +rust-version.workspace = true + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[dependencies] + +[lints] +workspace = true diff --git a/fastimer-driver/README.md b/fastimer-core/README.md similarity index 68% rename from fastimer-driver/README.md rename to fastimer-core/README.md index bc6c20e..b575a1e 100644 --- a/fastimer-driver/README.md +++ b/fastimer-core/README.md @@ -1,22 +1,22 @@ -# Fastimer Driver +# Fastimer Core API [![Crates.io][crates-badge]][crates-url] [![Documentation][docs-badge]][docs-url] [![MSRV 1.85][msrv-badge]](https://www.whatrustisit.com) -[crates-badge]: https://img.shields.io/crates/v/fastimer-driver.svg -[crates-url]: https://crates.io/crates/fastimer-driver -[docs-badge]: https://docs.rs/fastimer-driver/badge.svg +[crates-badge]: https://img.shields.io/crates/v/fastimer-core.svg +[crates-url]: https://crates.io/crates/fastimer-core +[docs-badge]: https://docs.rs/fastimer-core/badge.svg [msrv-badge]: https://img.shields.io/badge/MSRV-1.85-green?logo=rust -[docs-url]: https://docs.rs/fastimer-driver +[docs-url]: https://docs.rs/fastimer-core ## Overview -This crate implements a timer driver that can work with any async runtime scheduler. +This crate provides core APIs. ## Documentation -Read the online documents at https://docs.rs/fastimer-driver. +Read the online documents at https://docs.rs/fastimer-core. ## Minimum Supported Rust Version (MSRV) diff --git a/fastimer-core/src/lib.rs b/fastimer-core/src/lib.rs new file mode 100644 index 0000000..06dcd49 --- /dev/null +++ b/fastimer-core/src/lib.rs @@ -0,0 +1,46 @@ +//! # Fastimer Core APIs + +use std::future::Future; +use std::time::Duration; +use std::time::Instant; + +/// Create a far future instant. +pub fn far_future() -> Instant { + // Roughly 30 years from now. + // API does not provide a way to obtain max `Instant` + // or convert specific date in the future to instant. + // 1000 years overflows on macOS, 100 years overflows on FreeBSD. + Instant::now() + Duration::from_secs(86400 * 365 * 30) +} + +/// Create an instant from the given instant and a duration. +pub fn make_instant_from(now: Instant, dur: Duration) -> Instant { + now.checked_add(dur).unwrap_or_else(far_future) +} + +/// Create an instant from [`Instant::now`] and a duration. +pub fn make_instant_from_now(dur: Duration) -> Instant { + make_instant_from(Instant::now(), dur) +} + +/// A trait for creating delay futures. +/// +/// See [`MakeDelayExt`] for extension methods. +pub trait MakeDelay { + /// The future returned by the `delay`/`delay_until` method. + type Delay: Future + Send; + + /// Create a future that completes at the specified instant. + fn delay_util(&self, at: Instant) -> Self::Delay; + + /// Create a future that completes after the specified duration. + fn delay(&self, duration: Duration) -> Self::Delay { + self.delay_util(make_instant_from_now(duration)) + } +} + +/// A trait for spawning futures. +pub trait Spawn { + /// Spawn a future and return a cancellable future. + fn spawn + Send + 'static>(&self, future: F); +} diff --git a/fastimer-driver/Cargo.toml b/fastimer-driver/Cargo.toml deleted file mode 100644 index 4a7119c..0000000 --- a/fastimer-driver/Cargo.toml +++ /dev/null @@ -1,42 +0,0 @@ -# Copyright 2024 FastLabs Developers -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -[package] -name = "fastimer-driver" - -description = "This crate implements a timer driver that can work with any async runtime scheduler." -readme = "README.md" - -edition.workspace = true -homepage.workspace = true -license.workspace = true -repository.workspace = true -rust-version.workspace = true -version.workspace = true - -[package.metadata.docs.rs] -all-features = true -rustdoc-args = ["--cfg", "docsrs"] - -[dependencies] -atomic-waker = { version = "1.1.2" } -crossbeam-queue = { version = "0.3.12" } -fastimer = { workspace = true } -parking = { version = "2.2.1" } - -[dev-dependencies] -tokio = { workspace = true, features = ["full"] } - -[lints] -workspace = true diff --git a/fastimer-driver/src/heap.rs b/fastimer-driver/src/heap.rs deleted file mode 100644 index 7f69113..0000000 --- a/fastimer-driver/src/heap.rs +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright 2024 FastLabs Developers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::collections::BinaryHeap; -use std::ops::ControlFlow; -use std::sync::Arc; -use std::sync::atomic; -use std::sync::atomic::AtomicBool; -use std::time::Duration; -use std::time::Instant; - -use crossbeam_queue::SegQueue; -use parking::Parker; -use parking::Unparker; - -use crate::TimeContext; -use crate::TimeDriverShutdown; -use crate::TimeEntry; - -/// Returns a new time driver, its time context and the shutdown handle. -pub fn binary_heap_driver() -> (BinaryHeapTimeDriver, TimeContext, TimeDriverShutdown) { - let (parker, unparker) = parking::pair(); - let timers = BinaryHeap::new(); - let inbounds = Arc::new(SegQueue::new()); - let shutdown = Arc::new(AtomicBool::new(false)); - - let driver = BinaryHeapTimeDriver { - parker, - unparker, - timers, - inbounds, - shutdown, - }; - - let context = TimeContext { - unparker: driver.unparker.clone(), - inbounds: driver.inbounds.clone(), - }; - - let shutdown = TimeDriverShutdown { - unparker: driver.unparker.clone(), - shutdown: driver.shutdown.clone(), - }; - - (driver, context, shutdown) -} - -/// A heap-based time driver that drives registered timers. -#[derive(Debug)] -pub struct BinaryHeapTimeDriver { - parker: Parker, - unparker: Unparker, - timers: BinaryHeap, - inbounds: Arc>, - shutdown: Arc, -} - -impl BinaryHeapTimeDriver { - /// Drives the timers and returns `true` if the driver has been shut down. - pub fn turn(&mut self) -> ControlFlow<()> { - if self.shutdown.load(atomic::Ordering::Acquire) { - return ControlFlow::Break(()); - } - - match self.timers.peek() { - None => self.parker.park(), - Some(entry) => { - let delta = entry.when.saturating_duration_since(Instant::now()); - if delta > Duration::ZERO { - self.parker.park_timeout(delta); - } - } - } - - while let Some(entry) = self.inbounds.pop() { - self.timers.push(entry); - } - - while let Some(entry) = self.timers.peek() { - if entry.when <= Instant::now() { - entry.waker.wake(); - let _ = self.timers.pop(); - } else { - break; - } - } - - if self.shutdown.load(atomic::Ordering::Acquire) { - ControlFlow::Break(()) - } else { - ControlFlow::Continue(()) - } - } -} diff --git a/fastimer-driver/src/lib.rs b/fastimer-driver/src/lib.rs deleted file mode 100644 index 0cf2846..0000000 --- a/fastimer-driver/src/lib.rs +++ /dev/null @@ -1,159 +0,0 @@ -// Copyright 2024 FastLabs Developers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![deny(missing_docs)] - -//! Runtime-agnostic time driver for creating delay futures. - -use std::cmp; -use std::future::Future; -use std::pin::Pin; -use std::sync::Arc; -use std::sync::atomic; -use std::sync::atomic::AtomicBool; -use std::task::Context; -use std::task::Poll; -use std::time::Duration; -use std::time::Instant; - -use atomic_waker::AtomicWaker; -use crossbeam_queue::SegQueue; -use fastimer::MakeDelay; -use fastimer::make_instant_from_now; -use parking::Unparker; - -mod heap; -pub use heap::*; - -#[derive(Debug)] -struct TimeEntry { - when: Instant, - waker: Arc, -} - -impl PartialEq for TimeEntry { - fn eq(&self, other: &Self) -> bool { - self.when == other.when - } -} - -impl Eq for TimeEntry {} - -impl PartialOrd for TimeEntry { - fn partial_cmp(&self, other: &Self) -> Option { - Some(self.cmp(other)) - } -} - -impl Ord for TimeEntry { - fn cmp(&self, other: &Self) -> cmp::Ordering { - self.when.cmp(&other.when) - } -} - -/// Future returned by [`delay`] and [`delay_until`]. -/// -/// [`delay`]: TimeContext::delay -/// [`delay_until`]: TimeContext::delay_until -#[must_use = "futures do nothing unless you `.await` or poll them"] -#[derive(Debug)] -pub struct Delay { - when: Instant, - waker: Arc, -} - -impl Future for Delay { - type Output = (); - - fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll { - if Instant::now() >= self.when { - self.waker.take(); - Poll::Ready(()) - } else { - self.waker.register(cx.waker()); - Poll::Pending - } - } -} - -impl Drop for Delay { - fn drop(&mut self) { - self.waker.take(); - } -} - -/// A time context for creating [`Delay`]s. -#[derive(Debug, Clone)] -pub struct TimeContext { - unparker: Unparker, - inbounds: Arc>, -} - -impl TimeContext { - /// Returns a future that completes after the specified duration. - pub fn delay(&self, dur: Duration) -> Delay { - self.delay_until(make_instant_from_now(dur)) - } - - /// Returns a future that completes at the specified instant. - pub fn delay_until(&self, when: Instant) -> Delay { - let waker = Arc::new(AtomicWaker::new()); - let delay = Delay { - when, - waker: waker.clone(), - }; - self.inbounds.push(TimeEntry { when, waker }); - self.unparker.unpark(); - delay - } -} - -/// A handle to shut down the time driver. -#[derive(Debug, Clone)] -pub struct TimeDriverShutdown { - unparker: Unparker, - shutdown: Arc, -} - -impl TimeDriverShutdown { - /// Shuts down the time driver. - pub fn shutdown(&self) { - self.shutdown.store(true, atomic::Ordering::Release); - self.unparker.unpark(); - } -} - -/// A delay implementation that uses the given time context. -#[derive(Debug, Clone)] -pub struct MakeFastimerDelay(TimeContext); - -impl MakeFastimerDelay { - /// Create a new [`MakeFastimerDelay`] with the given [`TimeContext`]. - pub fn new(context: TimeContext) -> Self { - MakeFastimerDelay(context) - } -} - -impl MakeDelay for MakeFastimerDelay { - type Delay = Delay; - - fn delay_util(&self, at: Instant) -> Self::Delay { - self.0.delay_until(at) - } - - fn delay(&self, duration: Duration) -> Self::Delay { - self.0.delay(duration) - } -} diff --git a/fastimer-driver/tests/integration.rs b/fastimer-driver/tests/integration.rs deleted file mode 100644 index 6a26fe3..0000000 --- a/fastimer-driver/tests/integration.rs +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright 2024 FastLabs Developers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::time::Duration; -use std::time::Instant; - -use fastimer::make_instant_from_now; -use fastimer_driver::binary_heap_driver; - -#[track_caller] -fn assert_duration_eq(actual: Duration, expected: Duration) { - if expected.abs_diff(actual) > Duration::from_millis(250) { - panic!("expected: {:?}, actual: {:?}", expected, actual); - } -} - -#[test] -fn test_binary_heap_driver() { - let (mut driver, context, shutdown) = binary_heap_driver(); - let (tx, rx) = std::sync::mpsc::channel(); - std::thread::spawn(move || { - loop { - if driver.turn().is_break() { - tx.send(()).unwrap(); - break; - } - } - }); - - let rt = tokio::runtime::Runtime::new().unwrap(); - rt.block_on(async move { - let now = Instant::now(); - - context.delay(Duration::from_secs(2)).await; - assert_duration_eq(now.elapsed(), Duration::from_secs(2)); - - let now = Instant::now(); - let future = make_instant_from_now(Duration::from_secs(3)); - let f1 = context.delay_until(future); - let f2 = context.delay_until(future); - tokio::join!(f1, f2); - assert_duration_eq(now.elapsed(), Duration::from_secs(3)); - - shutdown.shutdown(); - }); - rx.recv_timeout(Duration::from_secs(1)).unwrap(); -} diff --git a/fastimer-tokio/Cargo.toml b/fastimer-tokio/Cargo.toml index ba16c9c..8844cdb 100644 --- a/fastimer-tokio/Cargo.toml +++ b/fastimer-tokio/Cargo.toml @@ -14,8 +14,9 @@ [package] name = "fastimer-tokio" +version = "0.10.0" -description = "This crate provides tokio runtime integration for fastimer." +description = "Fastimer integration for tokio runtime." readme = "README.md" edition.workspace = true @@ -23,18 +24,17 @@ homepage.workspace = true license.workspace = true repository.workspace = true rust-version.workspace = true -version.workspace = true [package.metadata.docs.rs] all-features = true rustdoc-args = ["--cfg", "docsrs"] [features] -spawn = ["dep:fastimer", "dep:tokio", "tokio/rt"] -time = ["dep:fastimer", "dep:tokio", "tokio/time"] +spawn = ["dep:fastimer-core", "dep:tokio", "tokio/rt"] +time = ["dep:fastimer-core", "dep:tokio", "tokio/time"] [dependencies] -fastimer = { workspace = true, optional = true } +fastimer-core = { workspace = true, optional = true } tokio = { workspace = true, optional = true } [lints] diff --git a/fastimer-tokio/README.md b/fastimer-tokio/README.md index 358bb9f..af74a47 100644 --- a/fastimer-tokio/README.md +++ b/fastimer-tokio/README.md @@ -1,4 +1,4 @@ -# Fastimer Tokio +# Fastimer Integration for Tokio [![Crates.io][crates-badge]][crates-url] [![Documentation][docs-badge]][docs-url] @@ -12,7 +12,7 @@ ## Overview -This crate provides tokio runtime integration for fastimer. +This crate provides timer traits, types, and utilities for fastimer. ## Documentation diff --git a/fastimer-tokio/src/lib.rs b/fastimer-tokio/src/lib.rs index 001c44f..d79f62e 100644 --- a/fastimer-tokio/src/lib.rs +++ b/fastimer-tokio/src/lib.rs @@ -12,10 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![deny(missing_docs)] +//! [`tokio`] runtime support for [`fastimer-core`]'s traits. +//! +//! [`fastimer-core`]: fastimer_core -//! [`tokio`] runtime support for [`fastimer`]'s traits. +#![cfg_attr(docsrs, feature(doc_cfg))] #[cfg(feature = "time")] pub use delay::*; @@ -25,11 +26,12 @@ mod delay { use std::time::Duration; use std::time::Instant; - use fastimer::MakeDelay; + use fastimer_core::MakeDelay; /// A delay implementation that uses Tokio's timer. #[derive(Clone, Copy, Debug, Default)] - pub struct MakeTokioDelay; + #[non_exhaustive] + pub struct MakeTokioDelay {} impl MakeDelay for MakeTokioDelay { type Delay = tokio::time::Sleep; @@ -51,7 +53,7 @@ pub use spawn::*; mod spawn { use std::future::Future; - use fastimer::Spawn; + use fastimer_core::Spawn; /// A spawn implementation that uses Tokio's runtime. #[derive(Clone, Debug, Default)] diff --git a/fastimer/Cargo.toml b/fastimer/Cargo.toml index 01df5a5..1b3ef13 100644 --- a/fastimer/Cargo.toml +++ b/fastimer/Cargo.toml @@ -14,8 +14,9 @@ [package] name = "fastimer" +version = "0.9.1" -description = "This crate implements runtime-agnostic timer traits and utilities." +description = "Runtime-agnostic timer traits and utilities" edition.workspace = true homepage.workspace = true @@ -23,7 +24,6 @@ license.workspace = true readme.workspace = true repository.workspace = true rust-version.workspace = true -version.workspace = true [package.metadata.docs.rs] all-features = true @@ -33,14 +33,16 @@ rustdoc-args = ["--cfg", "docsrs"] logging = ["dep:log"] [dependencies] -pin-project = { version = "1.1.9" } +fastimer-core = { workspace = true } +pin-project = { workspace = true } # optional dependencies -log = { version = "0.4.22", features = ["kv"], optional = true } +log = { workspace = true, optional = true } [dev-dependencies] -log = { version = "0.4.22", features = ["kv"] } -logforth = { version = "0.24.0", features = ["colored"] } +fastimer-tokio = { workspace = true, features = ["spawn", "time"] } +log = { workspace = true } +logforth = { workspace = true, features = ["starter-log"] } tokio = { workspace = true, features = ["full"] } [lints] diff --git a/fastimer/src/lib.rs b/fastimer/src/lib.rs index 6b719a6..cfbd80c 100644 --- a/fastimer/src/lib.rs +++ b/fastimer/src/lib.rs @@ -12,9 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![deny(missing_docs)] - //! Fastimer implements runtime-agnostic timer traits and utilities. //! //! # Scheduled Actions @@ -39,6 +36,8 @@ //! [`ArbitraryDelayAction`]: schedule::ArbitraryDelayAction //! [`NotifyAction`]: schedule::NotifyAction +#![cfg_attr(docsrs, feature(doc_cfg))] + use std::future::Future; use std::time::Duration; use std::time::Instant; @@ -51,46 +50,12 @@ pub use timeout::*; pub mod schedule; -/// Create a far future instant. -pub fn far_future() -> Instant { - // Roughly 30 years from now. - // API does not provide a way to obtain max `Instant` - // or convert specific date in the future to instant. - // 1000 years overflows on macOS, 100 years overflows on FreeBSD. - Instant::now() + Duration::from_secs(86400 * 365 * 30) -} - -/// Create an instant from the given instant and a duration. -pub fn make_instant_from(now: Instant, dur: Duration) -> Instant { - now.checked_add(dur).unwrap_or_else(far_future) -} - -/// Create an instant from [`Instant::now`] and a duration. -pub fn make_instant_from_now(dur: Duration) -> Instant { - make_instant_from(Instant::now(), dur) -} - -/// A trait for creating delay futures. -/// -/// See [`MakeDelayExt`] for extension methods. -pub trait MakeDelay { - /// The future returned by the `delay`/`delay_until` method. - type Delay: Future + Send; - - /// Create a future that completes at the specified instant. - fn delay_util(&self, at: Instant) -> Self::Delay; - - /// Create a future that completes after the specified duration. - fn delay(&self, duration: Duration) -> Self::Delay { - self.delay_util(make_instant_from_now(duration)) - } -} - -/// A trait for spawning futures. -pub trait Spawn { - /// Spawn a future and return a cancellable future. - fn spawn + Send + 'static>(&self, future: F); -} +// Re-export core traits and functions +pub use fastimer_core::MakeDelay; +pub use fastimer_core::Spawn; +pub use fastimer_core::far_future; +pub use fastimer_core::make_instant_from; +pub use fastimer_core::make_instant_from_now; /// Provides extension methods for [`MakeDelay`] implementors. pub trait MakeDelayExt: MakeDelay { @@ -147,7 +112,6 @@ mod macros { } #[cfg(not(any(test, feature = "logging")))] -#[macro_use] mod macros { macro_rules! info { (target: $target:expr, $($arg:tt)+) => {}; diff --git a/fastimer/src/schedule/arbitrary.rs b/fastimer/src/schedule/arbitrary.rs index 4bb3446..90f2f0c 100644 --- a/fastimer/src/schedule/arbitrary.rs +++ b/fastimer/src/schedule/arbitrary.rs @@ -18,11 +18,11 @@ use std::pin::pin; use std::time::Duration; use std::time::Instant; +use super::execute_or_shutdown; use crate::MakeDelay; use crate::Spawn; use crate::debug; use crate::info; -use crate::schedule::execute_or_shutdown; /// Repeatable action that can be scheduled with arbitrary delay. /// diff --git a/fastimer/src/schedule/notify.rs b/fastimer/src/schedule/notify.rs index 643a373..569c45b 100644 --- a/fastimer/src/schedule/notify.rs +++ b/fastimer/src/schedule/notify.rs @@ -16,11 +16,11 @@ use std::future::Future; use std::pin::pin; use std::time::Duration; +use super::execute_or_shutdown; use crate::MakeDelay; use crate::Spawn; use crate::debug; use crate::info; -use crate::schedule::execute_or_shutdown; /// Repeatable action that can be scheduled by notifications. /// diff --git a/fastimer/src/schedule/simple.rs b/fastimer/src/schedule/simple.rs index 2f0df20..c514a67 100644 --- a/fastimer/src/schedule/simple.rs +++ b/fastimer/src/schedule/simple.rs @@ -17,6 +17,7 @@ use std::pin::pin; use std::time::Duration; use std::time::Instant; +use super::execute_or_shutdown; use crate::MakeDelay; use crate::Spawn; use crate::debug; @@ -24,7 +25,6 @@ use crate::far_future; use crate::info; use crate::make_instant_from; use crate::make_instant_from_now; -use crate::schedule::execute_or_shutdown; /// Repeatable action. /// diff --git a/fastimer/tests/common/mod.rs b/fastimer/tests/common/mod.rs deleted file mode 100644 index 91cec84..0000000 --- a/fastimer/tests/common/mod.rs +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2024 FastLabs Developers -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -use std::time::Duration; -use std::time::Instant; - -use fastimer::MakeDelay; -use fastimer::Spawn; - -#[derive(Clone, Copy, Debug, Default)] -pub struct MakeTokioDelay; - -impl MakeDelay for MakeTokioDelay { - type Delay = tokio::time::Sleep; - - fn delay_util(&self, at: Instant) -> Self::Delay { - tokio::time::sleep_until(tokio::time::Instant::from_std(at)) - } - - fn delay(&self, duration: Duration) -> Self::Delay { - tokio::time::sleep(duration) - } -} - -#[derive(Clone, Copy, Debug, Default)] -pub struct TokioSpawn; - -impl Spawn for TokioSpawn { - fn spawn + Send + 'static>(&self, future: F) { - tokio::spawn(future); - } -} diff --git a/fastimer/tests/interval.rs b/fastimer/tests/interval.rs index 15c2c8b..1d3cdab 100644 --- a/fastimer/tests/interval.rs +++ b/fastimer/tests/interval.rs @@ -12,14 +12,15 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Tests for `Interval` with `tokio` runtime. + use std::time::Duration; use std::time::Instant; use fastimer::Interval; use fastimer::MakeDelay; use fastimer::MakeDelayExt; - -mod common; +use fastimer_tokio::MakeTokioDelay; #[track_caller] fn assert_duration_eq(actual: Duration, expected: Duration) { @@ -37,7 +38,7 @@ async fn assert_tick_about(interval: &mut Interval, expected: D #[tokio::test] async fn test_interval_ticks() { - let mut interval = common::MakeTokioDelay.interval(Duration::from_secs(1)); + let mut interval = MakeTokioDelay::default().interval(Duration::from_secs(1)); assert_tick_about(&mut interval, Duration::ZERO).await; for _ in 0..5 { @@ -49,7 +50,7 @@ async fn test_interval_ticks() { async fn test_interval_at_ticks() { let first_tick = Instant::now() + Duration::from_secs(2); - let mut interval = common::MakeTokioDelay.interval_at(first_tick, Duration::from_secs(1)); + let mut interval = MakeTokioDelay::default().interval_at(first_tick, Duration::from_secs(1)); assert_tick_about(&mut interval, Duration::from_secs(2)).await; for _ in 0..5 { diff --git a/fastimer/tests/schedule.rs b/fastimer/tests/schedule.rs index 0249b1a..b3a3c77 100644 --- a/fastimer/tests/schedule.rs +++ b/fastimer/tests/schedule.rs @@ -12,19 +12,18 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Tests for `schedule` module with `tokio` runtime. + use std::time::Duration; use std::time::Instant; use fastimer::MakeDelay; use fastimer::schedule::SimpleAction; use fastimer::schedule::SimpleActionExt; +use fastimer_tokio::MakeTokioDelay; +use fastimer_tokio::TokioSpawn; use logforth::append; -use crate::common::MakeTokioDelay; -use crate::common::TokioSpawn; - -mod common; - struct MySimpleAction { name: &'static str, counter: u8, @@ -43,37 +42,42 @@ impl SimpleAction for MySimpleAction { async fn run(&mut self) { log::info!("[{}] starting turn {}", self.name, self.counter); - MakeTokioDelay.delay(Duration::from_secs(1)).await; + MakeTokioDelay::default() + .delay(Duration::from_secs(1)) + .await; self.counter += 1; } } #[tokio::test] async fn test_simple_action() { - let _ = logforth::builder() + logforth::starter_log::builder() .dispatch(|d| d.append(append::Stderr::default())) - .try_apply(); + .apply(); + + let spawn = TokioSpawn::default(); + let make_delay = MakeTokioDelay::default(); let initial_delay = Some(Duration::from_secs(1)); let shutdown = Instant::now() + Duration::from_secs(10); MySimpleAction::new("schedule_with_fixed_delay").schedule_with_fixed_delay( - MakeTokioDelay.delay_util(shutdown), - &TokioSpawn, - MakeTokioDelay, + make_delay.delay_util(shutdown), + &spawn, + make_delay, initial_delay, Duration::from_secs(2), ); MySimpleAction::new("schedule_at_fixed_rate").schedule_at_fixed_rate( - MakeTokioDelay.delay_util(shutdown), - &TokioSpawn, - MakeTokioDelay, + make_delay.delay_util(shutdown), + &spawn, + make_delay, initial_delay, Duration::from_secs(2), ); - MakeTokioDelay + make_delay .delay_util(shutdown + Duration::from_secs(1)) .await; } diff --git a/xtask/Cargo.toml b/xtask/Cargo.toml index aaefba8..01ac906 100644 --- a/xtask/Cargo.toml +++ b/xtask/Cargo.toml @@ -27,8 +27,8 @@ rust-version.workspace = true release = false [dependencies] -clap = { version = "4.5.20", features = ["derive"] } -which = { version = "7.0.0" } +clap = { workspace = true } +which = { workspace = true } [lints] workspace = true diff --git a/xtask/src/main.rs b/xtask/src/main.rs index 8f0513b..ec6ab6e 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! `cargo x` subcommands for building, linting, and testing the workspace. + use std::process::Command as StdCommand; use clap::Parser; From 54ccf414ac7ed32a9c76b8ad79ef15da48c076dd Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 6 Oct 2025 23:45:08 +0800 Subject: [PATCH 2/3] fmt Signed-off-by: tison --- Cargo.toml | 2 +- fastimer-core/Cargo.toml | 14 ++++++++++++++ fastimer-core/src/lib.rs | 14 ++++++++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index b50064f..d8aa134 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,8 +20,8 @@ resolver = "2" edition = "2024" homepage = "https://github.com/fast/fastimer" license = "Apache-2.0" -repository = "https://github.com/fast/fastimer" readme = "README.md" +repository = "https://github.com/fast/fastimer" rust-version = "1.85.0" [workspace.dependencies] diff --git a/fastimer-core/Cargo.toml b/fastimer-core/Cargo.toml index 11f48b9..09c0df7 100644 --- a/fastimer-core/Cargo.toml +++ b/fastimer-core/Cargo.toml @@ -1,3 +1,17 @@ +# Copyright 2024 FastLabs Developers +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + [package] name = "fastimer-core" version = "0.1.0" diff --git a/fastimer-core/src/lib.rs b/fastimer-core/src/lib.rs index 0126288..ecce0f2 100644 --- a/fastimer-core/src/lib.rs +++ b/fastimer-core/src/lib.rs @@ -1,3 +1,17 @@ +// Copyright 2024 FastLabs Developers +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + //! # Fastimer Core APIs use std::future::Future; From 6ac7217874c0b80a851e19b766951fa19ea6e258 Mon Sep 17 00:00:00 2001 From: tison Date: Mon, 6 Oct 2025 23:48:48 +0800 Subject: [PATCH 3/3] docs Signed-off-by: tison --- fastimer-core/Cargo.toml | 2 -- fastimer-core/src/lib.rs | 13 +++++++++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/fastimer-core/Cargo.toml b/fastimer-core/Cargo.toml index 09c0df7..792fcc6 100644 --- a/fastimer-core/Cargo.toml +++ b/fastimer-core/Cargo.toml @@ -29,7 +29,5 @@ rust-version.workspace = true all-features = true rustdoc-args = ["--cfg", "docsrs"] -[dependencies] - [lints] workspace = true diff --git a/fastimer-core/src/lib.rs b/fastimer-core/src/lib.rs index ecce0f2..52ab31a 100644 --- a/fastimer-core/src/lib.rs +++ b/fastimer-core/src/lib.rs @@ -13,6 +13,17 @@ // limitations under the License. //! # Fastimer Core APIs +//! +//! Core traits: +//! +//! * [`MakeDelay`]: a trait for creating delay futures. +//! * [`Spawn`]: a trait for spawning futures, this is useful for scheduling tasks. +//! +//! Utility functions: +//! +//! * [`far_future`]: create a far future instant. +//! * [`make_instant_from`]: create an instant from the given instant and a duration. +//! * [`make_instant_from_now`]: create an instant from [`Instant::now`] and a duration. use std::future::Future; use std::time::Duration; @@ -38,8 +49,6 @@ pub fn make_instant_from_now(dur: Duration) -> Instant { } /// A trait for creating delay futures. -/// -/// See [`MakeDelayExt`] for extension methods. pub trait MakeDelay { /// The future returned by the `delay`/`delay_until` method. type Delay: Future + Send;