Skip to content

Commit 5856bdb

Browse files
authored
Next major update (#32)
* use dashmap and enable interior mutability * remove debug trait requirement * add support for other async-runtimes without feature flags clean up dep tree too * fix code coverage ci
1 parent 4c87de1 commit 5856bdb

File tree

8 files changed

+199
-203
lines changed

8 files changed

+199
-203
lines changed

.github/grcov.yml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
branch: true
2-
ignore-not-existing: true
3-
4-
output-type: lcov
5-
output-path: coverage
6-
ignore:
7-
- /tests/*
1+
branch: true
2+
ignore-not-existing: true
3+
4+
output-type: lcov
5+
output-path: coverage
6+
ignore:
7+
- /tests/*

.github/workflows/code_cov.yml

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Coverage
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
coverage:
13+
runs-on: ubuntu-latest
14+
15+
steps:
16+
- name: Checkout repository
17+
uses: actions/checkout@v4
18+
19+
- name: Cache Cargo dependencies
20+
uses: actions/cache@v3
21+
with:
22+
path: ~/.cargo/registry
23+
key: cargo-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
24+
restore-keys: |
25+
cargo-${{ runner.os }}-
26+
27+
- name: Install Rust nightly toolchain
28+
uses: dtolnay/rust-toolchain@nightly
29+
with:
30+
components: llvm-tools-preview
31+
32+
- name: Download and install grcov
33+
run: |
34+
GRCOV_VERSION="0.8.20"
35+
curl -L -o grcov.tar.bz2 "https://github.com/mozilla/grcov/releases/download/v$GRCOV_VERSION/grcov-x86_64-unknown-linux-gnu.tar.bz2"
36+
tar xjf grcov.tar.bz2
37+
chmod +x grcov
38+
mv grcov /usr/local/bin/
39+
40+
- name: Ensure target directory exists
41+
run: mkdir -p target/coverage
42+
43+
- name: Run tests with coverage
44+
run: |
45+
export CARGO_INCREMENTAL=0
46+
export RUSTFLAGS="-Cinstrument-coverage"
47+
export LLVM_PROFILE_FILE="$(pwd)/target/debug/deps/%p-%m.profraw"
48+
cargo +nightly test
49+
50+
- name: Locate LLVM Tools
51+
run: |
52+
echo "LLVM_TOOLS_DIR=$(rustc --print sysroot)/lib/rustlib/$(rustc -vV | grep host | awk '{print $2}')/bin" >> $GITHUB_ENV
53+
54+
- name: Download and install rustfilt
55+
run: |
56+
curl -L -o rustfilt "https://github.com/luser/rustfilt/releases/latest/download/rustfilt-x86_64-unknown-linux-gnu"
57+
chmod +x rustfilt
58+
mv rustfilt /usr/local/bin/
59+
60+
- name: Merge and Convert Coverage Data
61+
run: |
62+
$LLVM_TOOLS_DIR/llvm-profdata merge -sparse $(find target/debug/deps -name '*.profraw') -o target/coverage/merged.profdata
63+
$LLVM_TOOLS_DIR/llvm-cov export --format=lcov --instr-profile=target/coverage/merged.profdata \
64+
--ignore-filename-regex='/.cargo/registry|rustc/' \
65+
--Xdemangler=rustfilt $(find target/debug/deps -executable -type f) > target/coverage/lcov.info
66+
67+
- name: Verify Coverage File
68+
run: |
69+
ls -lah target/coverage/
70+
head -n 20 target/coverage/lcov.info
71+
72+
- name: Upload coverage report as artifact
73+
uses: actions/upload-artifact@v4
74+
with:
75+
name: coverage-report
76+
path: target/coverage/lcov.info
77+
78+
- name: Upload to Codecov
79+
uses: codecov/codecov-action@v4
80+
with:
81+
files: target/coverage/lcov.info
82+
fail_ci_if_error: true
83+
verbose: true
84+
env:
85+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

.github/workflows/codecov.yml

Lines changed: 0 additions & 54 deletions
This file was deleted.

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
/target
22
/Cargo.lock
33
*.idea/
4-
.vscode
4+
.vscode
5+
*.profraw

Cargo.toml

Lines changed: 23 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,39 +3,36 @@ name = "async-event-emitter"
33
version = "0.1.3"
44
edition = "2021"
55
description = "Lightweight AsyncEventEmitter"
6-
authors = [ "Spencer Najib", "Dylan Kerler" ]
7-
keywords = [ "event-emitter", "tokio", "async-rust", "futures", "bincode" ]
6+
authors = ["Spencer Najib", "Dylan Kerler"]
7+
keywords = ["event-emitter", "tokio", "async-rust", "futures", "bincode"]
88
license = "MIT"
99
repository = "https://github.com/spencerjibz/async-event-emitter-rs"
1010
homepage = "https://github.com/spencerjibz/async-event-emitter-rs"
11-
categories = [ "asynchronous", "web-programming" ]
11+
categories = ["asynchronous", "web-programming"]
1212
readme = "./README.md"
1313

1414
[dependencies]
15-
anyhow = "1.0.75"
15+
anyhow = "1.0.95"
1616
bincode = "1.3.3"
17-
futures = "0.3.29"
18-
lazy_static = "1.4.0"
19-
tokio-test = "0.4.3"
17+
futures = "0.3.31"
18+
lazy_static = "1.5.0"
2019

21-
[dependencies.async-std]
22-
version = "1.12.0"
23-
optional = true
24-
features = [ "alloc", "attributes" ]
20+
[dependencies.dashmap]
21+
version = "6.1.0"
22+
default-features = false
2523

26-
[dependencies.serde]
27-
version = "1.0.190"
28-
features = [ "derive" ]
24+
[dependencies.serde]
25+
version = "1.0.217"
26+
features = ["derive"]
27+
default-features = false
2928

30-
[dependencies.tokio]
31-
version = "1.33.0"
32-
features = [ "rt", "macros", "rt-multi-thread" ]
33-
optional = true
34-
35-
[dependencies.uuid]
36-
version = "1.5.0"
37-
features = [ "v4" ]
38-
39-
[features]
40-
use-async-std = [ "async-std" ]
41-
default = [ "tokio" ]
29+
[dependencies.uuid]
30+
version = "1.13.1"
31+
features = ["v4"]
32+
default-features = false
33+
[dev-dependencies]
34+
tokio = { version = "*", features = [
35+
"rt",
36+
"macros",
37+
"rt-multi-thread",
38+
], default-features = false }

README.md

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,20 @@ Allows you to subscribe to events with callbacks and also fire those events.
1212
Events are in the form of (strings, value) and callbacks are in the form of closures that take in a value parameter;
1313

1414
#### Differences between this crate and [`event-emitter-rs`](https://crates.io/crates/event-emitter-rs)
15+
- This is an async implementation that works for all common async runtimes (Tokio, async-std and smol)
16+
- The listener methods ***(on and once)*** take a callback that returns a future instead of a merely a closure.
17+
- The emit methods executes each callback on each event by spawning a tokio task instead of a std::thread
18+
- This emitter is thread safe and can also be used lock-free (supports interior mutability).
1519

16-
- Emitted values should implement an extra trait (Debug) in addition to Serde's Serialize and Deserialize.
17-
- This is an async implementation, not limited to tokio, but async-std is supported under the ``` use-async-std ``` feature flag.
18-
- The listener methods **_(on and once)_** take a callback that returns a future instead of a merely a closure.
19-
- The emit methods executes each callback on each event by spawning a tokio task instead of a std::thread
20+
***Note***: To use strict return and event types, use [typed-emitter](https://crates.io/crates/typed-emitter), that crate solves [this issue](https://github.com/spencerjibz/async-event-emitter-rs/issues/31) too.
2021

2122
#### Getting Started
2223

2324
```rust
2425
use async_event_emitter::AsyncEventEmitter;
2526
#[tokio::main]
2627
async fn main() {
27-
let mut event_emitter = AsyncEventEmitter::new();
28+
let event_emitter = AsyncEventEmitter::new();
2829
// This will print <"Hello world!"> whenever the <"Say Hello"> event is emitted
2930
event_emitter.on("Say Hello", |_: ()| async move { println!("Hello world!") });
3031
event_emitter.emit("Say Hello", ()).await.unwrap();
@@ -43,7 +44,7 @@ A single EventEmitter instance can have listeners to values of multiple types.
4344

4445
#[tokio::main]
4546
async fn main() -> anyhow::Result<()> {
46-
let mut event_emitter = EventEmitter::new();
47+
let event_emitter = EventEmitter::new();
4748
event_emitter.on("Add three", |number: f64| async move {
4849
println!("{}", number + 3.0)
4950
});
@@ -94,7 +95,7 @@ Removing listeners is also easy
9495

9596
```rust
9697
use async_event_emitter::AsyncEventEmitter as EventEmitter;
97-
let mut event_emitter = EventEmitter::new();
98+
let event_emitter = EventEmitter::new();
9899

99100
let listener_id = event_emitter.on("Hello", |_: ()| async { println!("Hello World") });
100101
match event_emitter.remove_listener(&listener_id) {
@@ -112,40 +113,31 @@ After all, one of the main points of using an EventEmitter is to avoid passing d
112113
```rust
113114
// global_event_emitter.rs
114115
use async_event_emitter::AsyncEventEmitter;
115-
use futures::lock::Mutex;
116116
use lazy_static::lazy_static;
117117

118118
// Use lazy_static! because the size of EventEmitter is not known at compile time
119119
lazy_static! {
120120
// Export the emitter with `pub` keyword
121-
pub static ref EVENT_EMITTER: Mutex<AsyncEventEmitter> = Mutex::new(AsyncEventEmitter::new());
121+
pub static ref EVENT_EMITTER: AsyncEventEmitter = AsyncEventEmitter::new();
122122
}
123123

124124
#[tokio::main]
125125
async fn main() -> anyhow::Result<()> {
126-
// We need to maintain a lock through the mutex so we can avoid data races
127-
EVENT_EMITTER
128-
.lock()
129-
.await
130-
.on("Hello", |_: ()| async { println!("hello there!") });
131-
EVENT_EMITTER.lock().await.emit("Hello", ()).await?;
126+
EVENT_EMITTER.on("Hello", |_: ()| async { println!("hello there!") });
127+
EVENT_EMITTER.emit("Hello", ()).await?;
132128

133129
Ok(())
134130
}
135131

136132
async fn random_function() {
137133
// When the <"Hello"> event is emitted in main.rs then print <"Random stuff!">
138134
EVENT_EMITTER
139-
.lock()
140-
.await
141135
.on("Hello", |_: ()| async { println!("Random stuff!") });
142136
}
143137

144138
```
145-
#### Using async-std instead of tokio
146-
Tokio is the default runtime for this library but async-std support can be able enabled by disabling default-features on the crate and enabling the ```use-async-std``` feature.
147-
<br>
148-
**Note**: Use simply replace tokio::main with async-std::main and tokio::test with async-std::test (provided you've enabled the "attributes" feature on the crate.
139+
#### Usage with other runtimes
140+
Check out the examples from the [typed version of this crate](https://docs.rs/typed-emitter/0.1.2/typed_emitter/#getting-started), just replace the emntter type.
149141

150142
#### Testing
151143
Run the tests on this crate with all-features enabled as follows:

0 commit comments

Comments
 (0)