···1616* `ZSTD_DICTIONARY` - The path to the ZSTD dictionary to use. Required when compression is enabled.
1717* `CONSUMER_TASK_ENABLE` - Whether or not to enable the consumer tasks. Default `true`.
1818* `VMC_TASK_ENABLE` - Whether or not to enable the VMC (verification method cache) tasks. Default `true`.
1919+* `CACHE_TASK_ENABLE` - Whether or not to enable the cache tasks. Default `true`.
2020+* `CACHE_TASK_INTERVAL` - The interval to run the cache tasks. Default `3m`.
2121+* `CLEANUP_TASK_ENABLE` - Whether or not to enable the cleanup tasks. Default `true`.
2222+* `CLEANUP_TASK_INTERVAL` - The interval to run the cleanup tasks. Default `1h`.
2323+* `CLEANUP_TASK_MAX_AGE` - The maximum age of a post before it is considered stale and deleted from storage. Default `48h`.
1924* `PLC_HOSTNAME` - The hostname of the PLC server to use for VMC tasks. Default `plc.directory`.
2025* `FEEDS` - The path to the feeds configuration file.
2126* `COLLECTIONS` - The collections to consume. Default `app.bsky.feed.post`.
+2-3
src/bin/dropsonde.rs
···11use anyhow::{anyhow, Context, Result};
22-use supercell::matcher::RhaiMatcher;
32use supercell::matcher::Matcher;
33+use supercell::matcher::RhaiMatcher;
4455fn main() -> Result<()> {
66 let mut rhai_input_path: Option<String> = None;
···2929 let value: serde_json::Value =
3030 serde_json::from_slice(&json_content).context("parsing input_json failed")?;
31313232- let matcher = RhaiMatcher::new(&rhai_input_path)
3333- .context("could not construct matcher")?;
3232+ let matcher = RhaiMatcher::new(&rhai_input_path).context("could not construct matcher")?;
3433 let result = matcher.matches(&value)?;
35343635 let result = result.ok_or(anyhow!("no matches found"))?;
+21-1
src/bin/supercell.rs
···55use std::env;
66use supercell::cache::Cache;
77use supercell::cache::CacheTask;
88+use supercell::cleanup::CleanTask;
89use supercell::vmc::VerificationMethodCacheTask;
910use tokio::net::TcpListener;
1011use tokio::signal;
···149150 });
150151 }
151152 }
153153+152154 {
153155 let inner_config = config.clone();
154156 let task_enable = *inner_config.cache_task_enable.as_ref();
···164166 let interval = *inner_config.cache_task_interval.as_ref();
165167 tracker.spawn(async move {
166168 if let Err(err) = task.run_background(interval).await {
167167- tracing::warn!(error = ?err, "consumer task error");
169169+ tracing::warn!(error = ?err, "cache task error");
170170+ }
171171+ inner_token.cancel();
172172+ });
173173+ }
174174+ }
175175+176176+ {
177177+ let inner_config = config.clone();
178178+ let task_enable = *inner_config.cleanup_task_enable.as_ref();
179179+ let max_age = *inner_config.cleanup_task_max_age.as_ref();
180180+ if task_enable {
181181+ let task = CleanTask::new(pool.clone(), max_age, token.clone());
182182+ task.main().await?;
183183+ let inner_token = token.clone();
184184+ let interval = *inner_config.cleanup_task_interval.as_ref();
185185+ tracker.spawn(async move {
186186+ if let Err(err) = task.run_background(interval).await {
187187+ tracing::warn!(error = ?err, "cleanup task error");
168188 }
169189 inner_token.cancel();
170190 });