ursula_runtime/
cold_worker.rs1use crate::PlanGroupColdFlushRequest;
6use crate::ShardRuntime;
7
8pub fn spawn_cold_flush_worker_if_configured(
10 runtime: &ShardRuntime,
11 config: &ursula_config::ColdConfig,
12) {
13 let interval = config.flush_interval.as_duration();
14 if interval.is_zero() {
15 return;
16 }
17 let min_hot_bytes = usize::try_from(config.flush_min_hot_size().as_bytes())
18 .expect("config validation ensures flush sizes fit usize");
19 let max_flush_bytes = usize::try_from(config.flush_max_size().as_bytes())
20 .expect("config validation ensures flush sizes fit usize");
21 let max_concurrency = config.flush_max_concurrency.max(1);
22 let runtime = runtime.clone();
23 tokio::spawn(async move {
24 loop {
25 if let Err(err) = runtime
26 .flush_cold_all_groups_once_bounded(
27 PlanGroupColdFlushRequest {
28 min_hot_bytes,
29 max_flush_bytes,
30 },
31 max_concurrency,
32 )
33 .await
34 {
35 tracing::error!("cold flush worker error: {err}");
36 }
37 tokio::time::sleep(interval).await;
38 }
39 });
40}
41
42pub fn spawn_cold_gc_worker_if_configured(
44 runtime: &ShardRuntime,
45 config: &ursula_config::ColdConfig,
46) {
47 let interval = config.gc_interval.as_duration();
48 if interval.is_zero() {
49 return;
50 }
51 let max_entries = config.gc_max_entries.max(1);
52 let runtime = runtime.clone();
53 tokio::spawn(async move {
54 loop {
55 if let Err(err) = runtime.run_cold_gc_all_groups_once(max_entries).await {
56 tracing::error!("cold gc worker error: {err}");
57 }
58 tokio::time::sleep(interval).await;
59 }
60 });
61}