pub struct Log { /* private fields */ }Expand description
Caller-owned heap history with fixed limits and monotonic append watermarks.
Implementations§
Source§impl Log
impl Log
Sourcepub const fn new(limits: Limits) -> Self
pub const fn new(limits: Limits) -> Self
Construct an empty log without preallocating the configured maximum.
Examples found in repository?
examples/worker.rs (lines 7-11)
6fn main() {
7 let mut log = Log::new(Limits {
8 max_entries: NonZeroUsize::new(8).expect("positive capacity"),
9 max_message_bytes: 32,
10 max_label_bytes: 16,
11 });
12 for (created_at_secs, level, message) in [
13 (10, Level::Info, "delivery accepted"),
14 (
15 11,
16 Level::Warn,
17 "provider reply is still unknown; reconcile before retry",
18 ),
19 (12, Level::Ok, "original delivery reconciled"),
20 ] {
21 log.append(EntryInput {
22 created_at_secs,
23 level,
24 source: "worker",
25 topic: Some("delivery"),
26 message,
27 })
28 .expect("valid bounded entry");
29 }
30 let page = log.page(
31 Filter::default(),
32 PageRequest {
33 before: None,
34 max_results: NonZeroUsize::new(8).expect("positive results"),
35 max_scanned: NonZeroUsize::new(8).expect("positive scan"),
36 },
37 );
38 for entry in page.entries {
39 println!("{} {:?}: {}", entry.sequence, entry.level, entry.message);
40 }
41 let batch = log.prune_expired(16, 5, 1);
42 assert_eq!(batch.removed, 1);
43 assert_eq!(log.next_expiry_secs(5), Some(17));
44}Sourcepub fn append(&mut self, input: EntryInput<'_>) -> Result<u64, AppendError>
pub fn append(&mut self, input: EntryInput<'_>) -> Result<u64, AppendError>
Admit one row and evict the oldest if the count ceiling is reached.
§Errors
Returns a typed refusal for oversized labels, regressed time or exhausted sequence identities. Validation completes before any eviction or mutation.
Examples found in repository?
examples/worker.rs (lines 21-27)
6fn main() {
7 let mut log = Log::new(Limits {
8 max_entries: NonZeroUsize::new(8).expect("positive capacity"),
9 max_message_bytes: 32,
10 max_label_bytes: 16,
11 });
12 for (created_at_secs, level, message) in [
13 (10, Level::Info, "delivery accepted"),
14 (
15 11,
16 Level::Warn,
17 "provider reply is still unknown; reconcile before retry",
18 ),
19 (12, Level::Ok, "original delivery reconciled"),
20 ] {
21 log.append(EntryInput {
22 created_at_secs,
23 level,
24 source: "worker",
25 topic: Some("delivery"),
26 message,
27 })
28 .expect("valid bounded entry");
29 }
30 let page = log.page(
31 Filter::default(),
32 PageRequest {
33 before: None,
34 max_results: NonZeroUsize::new(8).expect("positive results"),
35 max_scanned: NonZeroUsize::new(8).expect("positive scan"),
36 },
37 );
38 for entry in page.entries {
39 println!("{} {:?}: {}", entry.sequence, entry.level, entry.message);
40 }
41 let batch = log.prune_expired(16, 5, 1);
42 assert_eq!(batch.removed, 1);
43 assert_eq!(log.next_expiry_secs(5), Some(17));
44}Sourcepub fn prune_expired(
&mut self,
now_secs: u64,
max_age_secs: u64,
max_remove: usize,
) -> RetentionBatch
pub fn prune_expired( &mut self, now_secs: u64, max_age_secs: u64, max_remove: usize, ) -> RetentionBatch
Remove at most max_remove entries strictly older than the age cutoff.
An entry remains available through its full configured age second.
Examples found in repository?
examples/worker.rs (line 41)
6fn main() {
7 let mut log = Log::new(Limits {
8 max_entries: NonZeroUsize::new(8).expect("positive capacity"),
9 max_message_bytes: 32,
10 max_label_bytes: 16,
11 });
12 for (created_at_secs, level, message) in [
13 (10, Level::Info, "delivery accepted"),
14 (
15 11,
16 Level::Warn,
17 "provider reply is still unknown; reconcile before retry",
18 ),
19 (12, Level::Ok, "original delivery reconciled"),
20 ] {
21 log.append(EntryInput {
22 created_at_secs,
23 level,
24 source: "worker",
25 topic: Some("delivery"),
26 message,
27 })
28 .expect("valid bounded entry");
29 }
30 let page = log.page(
31 Filter::default(),
32 PageRequest {
33 before: None,
34 max_results: NonZeroUsize::new(8).expect("positive results"),
35 max_scanned: NonZeroUsize::new(8).expect("positive scan"),
36 },
37 );
38 for entry in page.entries {
39 println!("{} {:?}: {}", entry.sequence, entry.level, entry.message);
40 }
41 let batch = log.prune_expired(16, 5, 1);
42 assert_eq!(batch.removed, 1);
43 assert_eq!(log.next_expiry_secs(5), Some(17));
44}Sourcepub fn next_expiry_secs(&self, max_age_secs: u64) -> Option<u64>
pub fn next_expiry_secs(&self, max_age_secs: u64) -> Option<u64>
First second at which the oldest row expires; None for empty history or overflow.
Examples found in repository?
examples/worker.rs (line 43)
6fn main() {
7 let mut log = Log::new(Limits {
8 max_entries: NonZeroUsize::new(8).expect("positive capacity"),
9 max_message_bytes: 32,
10 max_label_bytes: 16,
11 });
12 for (created_at_secs, level, message) in [
13 (10, Level::Info, "delivery accepted"),
14 (
15 11,
16 Level::Warn,
17 "provider reply is still unknown; reconcile before retry",
18 ),
19 (12, Level::Ok, "original delivery reconciled"),
20 ] {
21 log.append(EntryInput {
22 created_at_secs,
23 level,
24 source: "worker",
25 topic: Some("delivery"),
26 message,
27 })
28 .expect("valid bounded entry");
29 }
30 let page = log.page(
31 Filter::default(),
32 PageRequest {
33 before: None,
34 max_results: NonZeroUsize::new(8).expect("positive results"),
35 max_scanned: NonZeroUsize::new(8).expect("positive scan"),
36 },
37 );
38 for entry in page.entries {
39 println!("{} {:?}: {}", entry.sequence, entry.level, entry.message);
40 }
41 let batch = log.prune_expired(16, 5, 1);
42 assert_eq!(batch.removed, 1);
43 assert_eq!(log.next_expiry_secs(5), Some(17));
44}Sourcepub fn page(&self, filter: Filter<'_>, request: PageRequest) -> Page<'_>
pub fn page(&self, filter: Filter<'_>, request: PageRequest) -> Page<'_>
Scan newest-first without cloning retained messages or counting every match.
Follow next_before with the same filters, including after an empty page.
Examples found in repository?
examples/worker.rs (lines 30-37)
6fn main() {
7 let mut log = Log::new(Limits {
8 max_entries: NonZeroUsize::new(8).expect("positive capacity"),
9 max_message_bytes: 32,
10 max_label_bytes: 16,
11 });
12 for (created_at_secs, level, message) in [
13 (10, Level::Info, "delivery accepted"),
14 (
15 11,
16 Level::Warn,
17 "provider reply is still unknown; reconcile before retry",
18 ),
19 (12, Level::Ok, "original delivery reconciled"),
20 ] {
21 log.append(EntryInput {
22 created_at_secs,
23 level,
24 source: "worker",
25 topic: Some("delivery"),
26 message,
27 })
28 .expect("valid bounded entry");
29 }
30 let page = log.page(
31 Filter::default(),
32 PageRequest {
33 before: None,
34 max_results: NonZeroUsize::new(8).expect("positive results"),
35 max_scanned: NonZeroUsize::new(8).expect("positive scan"),
36 },
37 );
38 for entry in page.entries {
39 println!("{} {:?}: {}", entry.sequence, entry.level, entry.message);
40 }
41 let batch = log.prune_expired(16, 5, 1);
42 assert_eq!(batch.removed, 1);
43 assert_eq!(log.next_expiry_secs(5), Some(17));
44}Trait Implementations§
Auto Trait Implementations§
impl Freeze for Log
impl RefUnwindSafe for Log
impl Send for Log
impl Sync for Log
impl Unpin for Log
impl UnsafeUnpin for Log
impl UnwindSafe for Log
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more