walr 0.1.7

Write Ahead Log(WAL) implementation using tokio
Documentation
//! Authors: Robert Lopez
//!
//! Basic example of persisting a Cache

use serde::{Deserialize, Serialize};
use std::{collections::HashMap, sync::Arc};
use tokio::sync::Mutex;
use walr::{ReplayHandlerResult, WAL};

type Cache = HashMap<String, String>;

#[derive(Serialize, Deserialize)]
enum CacheLog {
    Remove(String),
    Insert { key: String, value: String },
}

impl CacheLog {
    fn inner(self) -> (String, Option<String>) {
        match self {
            Self::Remove(key) => (key, None),
            Self::Insert { key, value } => (key, Some(value)),
        }
    }
}

type ReplayContext = ();

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    fn replay_handler(
        logs: Vec<CacheLog>,
        checkpoint: Arc<Mutex<Cache>>,
        context: Option<ReplayContext>,
    ) -> ReplayHandlerResult {
        Box::pin(async move {
            let mut checkpoint = checkpoint.lock().await;

            for log in logs {
                match log {
                    CacheLog::Insert { key, value } => checkpoint.insert(key, value),
                    CacheLog::Remove(key) => checkpoint.remove(&key),
                };
            }

            Ok(())
        })
    }

    let mut wal: WAL<CacheLog, Cache, ReplayContext> =
        WAL::open("./cache_wal", Box::new(replay_handler), None).await?;
    let mut cache = wal.replay(None).await?;

    let log = CacheLog::Insert {
        key: "some id".to_string(),
        value: "some data".to_string(),
    };

    wal.log(&log).await?;
    let (key, value) = log.inner();
    cache.insert(key, value.unwrap());

    let mut logs = vec![];

    for string in vec!["1".to_string(), "2".to_string()] {
        logs.push(CacheLog::Insert {
            key: string.clone(),
            value: string,
        });
    }

    wal.log_many(&logs).await?;
    for log in logs {
        let (key, value) = log.inner();
        cache.insert(key, value.unwrap());
    }

    wal.checkpoint(&cache).await?;

    Ok(())
}