p2panda_stream/log_prune/
processor.rs1use std::borrow::Borrow;
4use std::cell::RefCell;
5use std::collections::VecDeque;
6use std::marker::PhantomData;
7
8use p2panda_core::{Extensions, Hash, LogId, Operation, SeqNum, VerifyingKey};
9use p2panda_store::logs::LogStore;
10use thiserror::Error;
11use tokio::sync::Notify;
12
13use crate::Processor;
14use crate::log_prune::LogPruneArgs;
15
16pub struct LogPrune<S, T, L, E> {
17 store: S,
18 notify: Notify,
19 queue: RefCell<VecDeque<(T, LogPruneResult)>>,
20 _marker: PhantomData<(L, E)>,
21}
22
23impl<S, T, L, E> LogPrune<S, T, L, E>
24where
25 S: LogStore<Operation<E>, VerifyingKey, L, SeqNum, Hash>,
26 L: LogId,
27 E: Extensions,
28{
29 pub fn new(store: S) -> Self {
30 Self {
31 store,
32 notify: Notify::new(),
33 queue: RefCell::new(VecDeque::new()),
34 _marker: PhantomData,
35 }
36 }
37}
38
39impl<S, T, L, E> Processor<T> for LogPrune<S, T, L, E>
40where
41 S: LogStore<Operation<E>, VerifyingKey, L, SeqNum, Hash>,
42 T: Borrow<LogPruneArgs<VerifyingKey, L, SeqNum>>,
43 L: LogId,
44 E: Extensions,
45{
46 type Output = (T, LogPruneResult);
47
48 type Error = (T, LogPruneError);
49
50 async fn process(&self, input: T) -> Result<(), Self::Error> {
51 let args: &LogPruneArgs<VerifyingKey, L, SeqNum> = input.borrow();
52
53 let result = if let LogPruneArgs::PruneEntriesUntil {
54 author,
55 log_id,
56 seq_num,
57 } = args
58 {
59 match self.store.prune_entries(author, log_id, seq_num).await {
60 Ok(num_entries) => (input, LogPruneResult::Pruned { num_entries }),
61 Err(err) => {
62 return Err((input, LogPruneError::StoreError(err.to_string())));
65 }
66 }
67 } else {
68 (input, LogPruneResult::Noop)
69 };
70
71 self.queue.borrow_mut().push_back(result);
72 self.notify.notify_one(); Ok(())
75 }
76
77 async fn next(&self) -> Result<Self::Output, Self::Error> {
78 loop {
79 if let Some(item) = self.queue.borrow_mut().pop_front() {
80 return Ok(item);
81 }
82
83 self.notify.notified().await;
85 }
86 }
87}
88
89#[derive(Clone, Debug, PartialEq, Eq)]
90pub enum LogPruneResult {
91 Noop,
92 Pruned { num_entries: u64 },
93}
94
95#[derive(Clone, Debug, Error)]
96pub enum LogPruneError {
97 #[error("critical storage failure: {0}")]
99 StoreError(String),
100}