Rust error: lifetime may not live long enough, how to express lifetimes? - Stack Overflow

时间: 2025-01-06 admin 业界

I have a learning project where I am building a segmented WAL, and I am implementing Stream for both the log files, and the overall WAL (segments transparent) at .rs#L529-L556

Currently, I am stuck with the compiler error:

   Compiling writeahead v0.1.0 (/Users/dangoodman/code/WriteAhead)
warning: unused import: `TryStreamExt`
 --> src/write_ahead.rs:2:23
  |
2 | use futures::{Stream, TryStreamExt};
  |                       ^^^^^^^^^^^^
  |
  = note: `#[warn(unused_imports)]` on by default

error: lifetime may not live long enough
   --> src/write_ahead.rs:515:28
    |
497 |   impl<'a, F: FileIO> WriteAheadStream<'a, F> {
    |        -- lifetime `'a` defined here
...
510 |       fn advance_to_next_stream(&mut self) -> Option<()> {
    |                                 - let's call the lifetime of this reference `'1`
...
515 |           let next_logfile = self
    |  ____________________________^
516 | |             .write_ahead
517 | |             .log_files
518 | |             .get_mut(&self.current_logfile_id)?;
    | |______________________________________________^ argument requires that `'1` must outlive `'a`

warning: `writeahead` (lib) generated 1 warning
error: could not compile `writeahead` (lib) due to 1 previous error; 1 warning emitted

Here's a cut-down version of the code with the problem:

use std::collections::BTreeMap;

pub struct Logfile<F> {
    fio: F,
}

pub struct LogFileStream<'a, F> {
    logfile: &'a mut Logfile<F>,
}

impl<'a, F> LogFileStream<'a, F> {
    pub fn new(logfile: &'a mut Logfile<F>) -> Self {
        Self { logfile }
    }
}

pub struct WriteAhead<F> {
    log_files: BTreeMap<u64, Logfile<F>>,
}

pub struct WriteAheadStream<'a, F> {
    write_ahead: &'a mut WriteAhead<F>,
    current_logfile_id: u64,
    current_stream: Option<LogFileStream<'a, F>>,
}

impl<'a, F> WriteAheadStream<'a, F> {
    // Helper to get next stream when current one is exhausted
    fn advance_to_next_stream(&mut self) -> Option<()> {
        // If we have an active stream, drop it
        self.current_stream = None;

        // Try to get next logfile
        let next_logfile = self
            .write_ahead
            .log_files
            .get_mut(&self.current_logfile_id)?;

        // Create new stream
        self.current_stream = Some(LogFileStream::new(next_logfile));
        self.current_logfile_id += 1;
        Some(())
    }
}

I'm unsure how I can express that this should outlive it. My expectation that this WriteAhead is going to be single threaded and own the lifetime of both Logfiles, LogFileStream, and WriteAheadStreams.

Perhaps I'm not expressing that ownership hierarchy well enough, but I'm unsure how to do that. The goal would be that something like Axum or another network service could wrap this in an Arc<Mutex<>> to utilize it, but responses that want to stream the WAL in a single response can use the WriteAheadStream.