Skip to content

Add lifecycle notification APIs for embedded applications #180

@JoshuaChi

Description

@JoshuaChi

Problem Statement

Applications embedding d-engine need to know about key lifecycle events:

  • When is d-engine ready to serve requests?
  • When should the application gracefully shut down?
  • When does leadership change (for read optimization)?

Reference: embed package

  • ReadyNotify() - notifies when server is ready
  • StopNotify() - notifies when server is stopping

Current Gap

d-engine lacks these notification APIs. Applications must:

  • Poll to check if d-engine is ready (inefficient)
  • Cannot detect leadership changes proactively
  • No graceful shutdown coordination

Proposed APIs

Must Have:

pub trait LifecycleNotifier {
    /// Notifies when d-engine is ready to serve requests
    /// Returns a channel that closes when ready
    fn ready_notify(&self) -> Receiver<()>;
    
    /// Notifies when d-engine is stopping
    /// Returns a channel that closes when stopping
    fn stop_notify(&self) -> Receiver<()>;
    
    /// Notifies when leader changes
    /// Returns a channel that receives new leader ID
    fn leader_changed_notify(&self) -> Receiver<NodeId>;
    
    /// Returns current leader node ID
    fn current_leader(&self) -> Option<NodeId>;
}

Nice to Have (optimization):

    /// Returns current Raft term
    fn current_term(&self) -> u64;
    
    /// Notifies when first commit happens after becoming leader
    /// Useful for optimizing read-your-writes
    fn first_commit_notify(&self) -> Receiver<u64>;

Use Case Example

d-queue integration:

let d_engine = DEmbedded::new(config)?;

// Wait for d-engine to be ready
d_engine.ready_notify().await;
println!("d-engine is ready, starting d-queue broker");

// Monitor leadership changes
tokio::spawn(async move {
    loop {
        let leader = d_engine.leader_changed_notify().await;
        println!("New leader elected: {:?}", leader);
        // Optimize: redirect writes to leader
    }
});

// Graceful shutdown
tokio::select! {
    _ = d_engine.stop_notify() => {
        println!("d-engine is stopping, shutting down d-queue");
    }
    _ = shutdown_signal() => {
        println!("Shutdown signal received");
    }
}

Implementation Notes

  • Should work for both embedded and standalone modes
  • Use Tokio channels for async notifications
  • Add integration tests with d-queue as example

Metadata

Metadata

Assignees

No one assigned

    Labels

    component:client-kvCore KV API — get, put, delete, batch write, scan, range queries.deploy:embeddedRaft consensus engine embedded directly within the application process.

    Projects

    Status

    Backlog

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions