Skip to content

Commit 73ddde3

Browse files
committed
feat: Optimized use of internal time-wheel memory
1 parent 948dc49 commit 73ddde3

File tree

12 files changed

+106
-16
lines changed

12 files changed

+106
-16
lines changed

CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
# Version 0.10.0
2+
3+
## Changed
4+
Optimized the use of internal `time-wheel` memory. ([#28](https://github.com/BinChengZhao/delay-timer/issues/28)), thanks `elderbig` !
5+
6+
### Details
7+
There is a `time-wheel` in `delay-timer`, which is the carrier of all tasks.
8+
9+
The time wheel uses slots (time scales) as units, each slot corresponds to a hash table, when a slot is rotated to it will execute the task that is already ready internally, when the task is executed it will move from one slot to another. In order to have enough capacity to store the tasks, there may be a memory allocation here, so that by the time the whole time wheel is traversed, each internal time wheel-slot will have rich memory capacity, and when there are many tasks the memory occupied by the whole time wheel will be very large. So it will be necessary to shrink the memory in time.
10+
11+
This change is to shrink the memory in time after each round of training slots and executing tasks to ensure that the slots have a basic and compact capacity.
12+
113
# Version 0.9.2
214

315
## Changed

Cargo.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "delay_timer"
3-
version = "0.9.2"
3+
version = "0.10.0"
44
authors = ["binchengZhao <binchengZhao@outlook.com>"]
55
edition = "2018"
66
repository = "https://github.com/BinChengZhao/delay-timer"
@@ -49,6 +49,8 @@ tokio = { version = "^1.3.0", features = ["full"] , optional = true }
4949
[dev-dependencies]
5050
rand = "0.8.4"
5151
surf = "^2.1.0"
52+
tracing = "0.1.29"
53+
tracing-subscriber = "0.2.0"
5254
tokio = { version = "^1.3.0", features = ["full"] }
5355
hyper= {version = "^0.14.2" , features = ["full"] }
5456
pretty_env_logger = "^0.4"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ pub fn generate_closure_template(
194194

195195
let future = async move {
196196
future_inner.await;
197-
context.finishe_task().await;
197+
context.finish_task().await;
198198
};
199199
create_delay_task_handler(async_spawn(future))
200200
}

examples/cycle_tokio_task.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ pub fn generate_closure_template(
6464

6565
let future = async move {
6666
future_inner.await.ok();
67-
context.finishe_task(None).await;
67+
context.finish_task(None).await;
6868
};
6969

7070
create_delay_task_handler(async_spawn_by_tokio(future))

examples/demo.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ pub fn generate_closure_template(
110110

111111
let future = async move {
112112
future_inner.await;
113-
context.finishe_task(None).await;
113+
context.finish_task(None).await;
114114
};
115115
create_delay_task_handler(async_spawn(future))
116116
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#![allow(deprecated)]
2+
3+
use anyhow::Result;
4+
use delay_timer::prelude::*;
5+
use smol::Timer;
6+
use std::time::Duration;
7+
use tracing::{info, Level};
8+
use tracing_subscriber::FmtSubscriber;
9+
10+
#[async_std::main]
11+
async fn main() -> Result<()> {
12+
// a builder for `FmtSubscriber`.
13+
FmtSubscriber::builder()
14+
// all spans/events with a level higher than TRACE (e.g, debug, info, warn, etc.)
15+
// will be written to stdout.
16+
.with_max_level(Level::DEBUG)
17+
// completes the builder.
18+
.init();
19+
20+
let delay_timer = DelayTimerBuilder::default().build();
21+
for i in 0..1000 {
22+
delay_timer.add_task(build_task_async_execute_process(i)?)?;
23+
}
24+
25+
info!("==== All job is be init! ====");
26+
for _ in 0..120 {
27+
Timer::after(Duration::from_secs(60)).await;
28+
}
29+
Ok(delay_timer.stop_delay_timer()?)
30+
}
31+
32+
fn build_task_async_execute_process(task_id: u64) -> Result<Task, TaskError> {
33+
let mut task_builder = TaskBuilder::default();
34+
35+
let body = unblock_process_task_fn("echo hello".into());
36+
task_builder
37+
.set_frequency_by_candy(CandyFrequency::Repeated(CandyCron::Secondly))
38+
.set_task_id(task_id)
39+
.set_maximum_running_time(10)
40+
.set_maximum_parallel_runnable_num(1)
41+
.spawn(body)
42+
}

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@
207207
//!
208208
//! let future = async move {
209209
//! future_inner.await;
210-
//! context.finishe_task(None).await;
210+
//! context.finish_task(None).await;
211211
//! };
212212
//!
213213
//! create_delay_task_handler(async_spawn(future))

src/macros/generate_fn_macro.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ macro_rules! create_async_fn_body {
1414
let future_inner = async move { $async_body };
1515
future_inner.await;
1616

17-
context.finishe_task(None).await;
17+
context.finish_task(None).await;
1818
};
1919
let handle = async_spawn(f);
2020
create_delay_task_handler(handle)
@@ -34,7 +34,7 @@ macro_rules! create_async_fn_body {
3434
let future_inner = async move { $async_body };
3535
future_inner.await;
3636

37-
context.finishe_task(None).await;
37+
context.finish_task(None).await;
3838
};
3939
let handle = async_spawn(f);
4040
create_delay_task_handler(handle)
@@ -53,7 +53,7 @@ cfg_tokio_support!(
5353
let future_inner = async move { $async_body };
5454
future_inner.await;
5555

56-
context.finishe_task().await;
56+
context.finish_task().await;
5757
});
5858
create_delay_task_handler(handle)
5959
}
@@ -71,7 +71,7 @@ cfg_tokio_support!(
7171
let future_inner = async move { $async_body };
7272
future_inner.await;
7373

74-
context.finishe_task().await;
74+
context.finish_task().await;
7575
};
7676
let handle = async_spawn(f);
7777
create_delay_task_handler(handle)

src/timer/slot.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ impl Slot {
3838
self.task_map.remove(&task_id)
3939
}
4040

41-
//Check and reduce cylinder_line,
42-
//Returns a Vec. containing all task ids to be executed.(cylinder_line == 0)
41+
// Check and reduce cylinder_line,
42+
// Returns a Vec. containing all task ids to be executed.(cylinder_line == 0)
4343
pub(crate) fn arrival_time_tasks(&mut self) -> Vec<u64> {
4444
let mut task_id_vec = vec![];
4545

@@ -51,4 +51,11 @@ impl Slot {
5151

5252
task_id_vec
5353
}
54+
55+
// When the operation is finished with the task, shrink the container in time
56+
// To avoid the overall time-wheel from occupying too much memory.
57+
// FIX: https://github.com/BinChengZhao/delay-timer/issues/28
58+
pub(crate) fn shrink(&mut self) {
59+
self.task_map.shrink_to(64);
60+
}
5461
}

src/timer/task.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -498,7 +498,7 @@ impl TaskContext {
498498
}
499499

500500
/// Send a task-Finish signal to EventHandle.
501-
pub async fn finishe_task(self, finish_output: Option<FinishOutput>) {
501+
pub async fn finish_task(self, finish_output: Option<FinishOutput>) {
502502
if let Some(timer_event_sender) = self.timer_event_sender {
503503
timer_event_sender
504504
.send(TimerEvent::FinishTask(FinishTaskBody {

0 commit comments

Comments
 (0)