### Install cargo-fuzz Source: https://github.com/tokahuke/yaque/blob/master/fuzz/readme.md Installs the cargo-fuzz utility required for running fuzz tests. ```bash cargo install cargo-fuzz ``` -------------------------------- ### Initialize Fuzz Data Directory Source: https://github.com/tokahuke/yaque/blob/master/fuzz/readme.md Creates a temporary directory for fuzzing data and outputs the path. ```bash export YAQUE_FUZZ_BASE_DIR=`mktemp -d yaque-fuzz-XXXX --tmpdir` echo "${YAQUE_FUZZ_BASE_DIR}" ``` -------------------------------- ### Create a Yaque channel Source: https://github.com/tokahuke/yaque/blob/master/readme.md Initializes a new queue at the specified directory path. ```rust use yaque::channel; futures::executor::block_on(async { let (mut sender, mut receiver) = channel("data/my-queue").unwrap(); }) ``` -------------------------------- ### Create a Queue Channel Source: https://context7.com/tokahuke/yaque/llms.txt Initializes both sender and receiver ends of a queue mounted on a directory path. ```rust use yaque::channel; futures::executor::block_on(async { // Create a queue channel with sender and receiver let (mut sender, mut receiver) = channel("data/my-queue").unwrap(); // Send data to the queue sender.send(b"hello world").await.unwrap(); // Receive data from the queue let data = receiver.recv().await.unwrap(); assert_eq!(&*data, b"hello world"); // Commit the read to make it permanent data.commit().unwrap(); }); ``` -------------------------------- ### Send and receive data with transactional commit Source: https://github.com/tokahuke/yaque/blob/master/readme.md Demonstrates basic send and receive operations, including the requirement to commit data to make changes permanent. ```rust use yaque::{channel, queue::try_clear}; futures::executor::block_on(async { // Open using the `channel` function or directly with the constructors. let (mut sender, mut receiver) = channel("data/my-queue").unwrap(); // Send stuff with the sender... sender.send(b"some data").await.unwrap(); // ... and receive it in the other side. let data = receiver.recv().await.unwrap(); assert_eq!(&*data, b"some data"); // Call this to make the changes to the queue permanent. // Not calling it will revert the state of the queue. data.commit(); }); // After everything is said and done, you may delete the queue. // Use `clear` for awaiting for the queue to be released. try_clear("data/my-queue").unwrap(); ``` -------------------------------- ### Configure Nightly Toolchain Source: https://github.com/tokahuke/yaque/blob/master/fuzz/readme.md Sets the Rust toolchain to nightly within the fuzz directory. ```bash cd fuzz rustup override set nightly ``` -------------------------------- ### QueueIter Source: https://context7.com/tokahuke/yaque/llms.txt Provides synchronous iteration over queue elements without transactional overhead. ```APIDOC ## QueueIter ### Description Provides synchronous iteration over queue elements without transactional overhead, ideal for reading stored data. ``` -------------------------------- ### Execute Fuzz Tests Source: https://github.com/tokahuke/yaque/blob/master/fuzz/readme.md Runs the queue_operations fuzz target. ```bash cargo fuzz run queue_operations ``` -------------------------------- ### Configure Sender with Builder Source: https://context7.com/tokahuke/yaque/llms.txt Uses SenderBuilder to set segment sizes and queue limits, including handling full queue errors. ```rust use yaque::SenderBuilder; // Create sender with custom configuration let mut sender = SenderBuilder::new() .segment_size(512) // 512 bytes per segment (default: 4MB) .max_queue_size(Some(2048)) // Maximum 2KB queue size (default: None/unlimited) .open("data/custom-queue") .unwrap(); // Send data - will block if queue is full futures::executor::block_on(async { sender.send(b"data with size limits").await.unwrap(); }); // Or use try_send to handle full queue without blocking use yaque::TrySendError; match sender.try_send(b"more data") { Ok(()) => println!("Sent successfully"), Err(TrySendError::QueueFull { .. }) => println!("Queue is full, try later"), Err(TrySendError::Io(err)) => panic!("IO error: {}", err), } ``` -------------------------------- ### Configure Receiver with Save Policies Source: https://context7.com/tokahuke/yaque/llms.txt Customizes crash recovery behavior by defining how often the receiver state is saved to disk. ```rust use yaque::ReceiverBuilder; use std::time::Duration; // Create receiver with custom save policies let mut receiver = ReceiverBuilder::new() .save_every_nth(Some(100)) // Save every 100 elements (default: 250) .save_every(Some(Duration::from_millis(500))) // Save every 500ms (default: 350ms) .open("data/custom-receiver-queue") .unwrap(); futures::executor::block_on(async { let data = receiver.recv().await.unwrap(); data.commit().unwrap(); }); ``` -------------------------------- ### Send Batches Source: https://context7.com/tokahuke/yaque/llms.txt Sends multiple items atomically in a single disk operation for improved performance. ```rust use yaque::Sender; let mut sender = Sender::open("data/batch-queue").unwrap(); // Prepare batch data let batch_data: Vec<&[u8]> = vec![ b"item 1", b"item 2", b"item 3", b"item 4", ]; // Send batch synchronously (non-blocking) sender.try_send_batch(&batch_data).unwrap(); // Or send batch asynchronously (blocks if queue full) futures::executor::block_on(async { let more_data = vec![b"item 5", b"item 6"]; sender.send_batch(&more_data).await.unwrap(); }); ``` -------------------------------- ### Use a persistent mutex Source: https://context7.com/tokahuke/yaque/llms.txt Implements a disk-backed mutex for cross-process synchronization. Locks are released when the guard is dropped. ```rust use yaque::mutex::Mutex; futures::executor::block_on(async { // Open a persistent mutex let mutex = Mutex::open("data/my-mutex").unwrap(); // Acquire lock asynchronously let guard = mutex.lock().await.unwrap(); // Write data while holding the lock guard.write(b"protected content").unwrap(); // Read data let content = guard.read().unwrap(); assert_eq!(content, b"protected content"); // Lock released when guard is dropped drop(guard); // Try lock (non-blocking) if let Some(guard) = mutex.try_lock().unwrap() { let data = guard.read().unwrap(); println!("Read: {:?}", data); } else { println!("Mutex is locked by another process"); } }); ``` -------------------------------- ### Synchronous Queue Iteration with Yaque Source: https://context7.com/tokahuke/yaque/llms.txt Use `QueueIter` for synchronous, non-transactional iteration over queue elements. This is suitable for reading stored data without affecting the queue's transactional state. Requires releasing the sender lock first. ```rust use yaque::{Sender, QueueIter}; // Populate the queue let mut sender = Sender::open("data/iter-queue").unwrap(); sender.try_send_batch(&[b"first", b"second", b"third"]).unwrap(); drop(sender); // Release sender lock // Iterate synchronously over queue contents let items: Vec> = QueueIter::open("data/iter-queue") .unwrap() .map(|result| result.unwrap()) .collect(); assert_eq!(items.len(), 3); assert_eq!(items[0], b"first"); assert_eq!(items[1], b"second"); assert_eq!(items[2], b"third"); ``` -------------------------------- ### Receive data with a timeout Source: https://github.com/tokahuke/yaque/blob/master/readme.md Uses a future to implement a timeout for receiving data from the queue. ```rust use yaque::channel; use std::time::Duration; use futures_timer::Delay; futures::executor::block_on(async { let (mut sender, mut receiver) = channel("data/my-queue-2").unwrap(); // receive some data up to a second let data = receiver .recv_timeout(Delay::new(Duration::from_secs(1))) .await .unwrap(); // Nothing was sent, so no data... assert!(data.is_none()); drop(data); // ... but if you do send something... sender.send(b"some data").await.unwrap(); // ... now you receive something: let data = receiver .recv_timeout(Delay::new(Duration::from_secs(1))) .await .unwrap(); assert_eq!(&*data.unwrap(), b"some data"); }); ``` -------------------------------- ### Recover a queue after a crash Source: https://context7.com/tokahuke/yaque/llms.txt Restores a queue to a consistent state after a crash. Use recovery for idempotent processing or recover_with_loss to discard segments. ```rust use yaque::{channel, recovery}; // Simulate crash scenario - queue left in inconsistent state // (In real use, this happens from kill -9, power loss, etc.) // Recover the queue with possible replay of some elements recovery::recover("data/crashed-queue").unwrap(); // Queue can now be opened normally futures::executor::block_on(async { let (mut sender, mut receiver) = channel("data/crashed-queue").unwrap(); // Continue operations... sender.send(b"after recovery").await.unwrap(); let data = receiver.recv().await.unwrap(); data.commit().unwrap(); }); ``` ```rust use yaque::{channel, recovery}; // Recover with data loss (use when replays are unacceptable) // This erases the bottom segment to guarantee no duplicates recovery::recover_with_loss("data/corrupted-queue").unwrap(); // Queue can now be opened - some data may be lost futures::executor::block_on(async { let (mut sender, mut receiver) = channel("data/corrupted-queue").unwrap(); sender.send(b"fresh start").await.unwrap(); }); ``` -------------------------------- ### recv_timeout Source: https://context7.com/tokahuke/yaque/llms.txt Receives data with a timeout, returning None if the timeout elapses before data arrives. ```APIDOC ## recv_timeout ### Description Allows receiving data with a timeout, returning None if the timeout elapses before data arrives. ### Parameters #### Request Body - **timeout** (Delay) - Required - The duration to wait for data. ``` -------------------------------- ### recv_batch_timeout Source: https://context7.com/tokahuke/yaque/llms.txt Attempts to receive up to n elements within a time limit, returning whatever was collected. ```APIDOC ## recv_batch_timeout ### Description Attempts to receive up to n elements within a time limit, returning whatever was collected. ### Parameters #### Request Body - **n** (usize) - Required - Maximum number of elements to collect. - **timeout** (Delay) - Required - The duration to wait. ``` -------------------------------- ### recv_batch Source: https://context7.com/tokahuke/yaque/llms.txt Receives exactly n elements, waiting until all are available. Returns a guard for transactional commit/rollback. ```APIDOC ## recv_batch ### Description Receives exactly n elements, waiting until all are available. Returns a guard for transactional commit/rollback. ### Parameters #### Request Body - **n** (usize) - Required - The number of elements to receive. ``` -------------------------------- ### Receive elements until a condition is met Source: https://context7.com/tokahuke/yaque/llms.txt Uses an async predicate to batch process elements from a channel until the condition returns true. ```rust use yaque::channel; futures::executor::block_on(async { let (mut sender, mut receiver) = channel("data/recv-until-queue").unwrap(); // Send messages with an empty terminator sender.try_send(b"msg1").unwrap(); sender.try_send(b"msg2").unwrap(); sender.try_send(b"").unwrap(); // Empty = terminator sender.try_send(b"msg3").unwrap(); // Receive until empty message (terminator not included in result) let batch = receiver .recv_until(|element| async move { element.map(|e| e.is_empty()).unwrap_or(false) }) .await .unwrap(); assert_eq!(batch.len(), 2); assert_eq!(&*batch[0], b"msg1"); assert_eq!(&*batch[1], b"msg2"); batch.commit().unwrap(); }); ``` -------------------------------- ### Batch Receive with Timeout in Yaque Source: https://context7.com/tokahuke/yaque/llms.txt Use `recv_batch_timeout` to attempt receiving up to `n` elements within a time limit. Returns whatever elements were collected before the timeout. Requires `futures_timer` crate. ```rust use yaque::channel; use std::time::Duration; use futures_timer::Delay; futures::executor::block_on(async { let (mut sender, mut receiver) = channel("data/batch-timeout-queue").unwrap(); // Send 3 items sender.try_send(b"1").unwrap(); sender.try_send(b"2").unwrap(); sender.try_send(b"3").unwrap(); // Try to receive 5 items with timeout - will get 3 let batch = receiver .recv_batch_timeout(5, Delay::new(Duration::from_millis(100))) .await .unwrap(); assert_eq!(batch.len(), 3); batch.commit().unwrap(); }); ``` -------------------------------- ### try_recv Source: https://context7.com/tokahuke/yaque/llms.txt Attempts to receive without waiting, returning an error if the queue is empty. ```APIDOC ## try_recv ### Description Attempts to receive without waiting, returning an error if the queue is empty. ``` -------------------------------- ### Receive Exactly N Elements with Yaque Source: https://context7.com/tokahuke/yaque/llms.txt Use `recv_batch` to receive a specific number of elements, ensuring all are available before proceeding. Returns a guard for transactional commit or rollback. ```rust use yaque::channel; futures::executor::block_on(async { let (mut sender, mut receiver) = channel("data/recv-batch-queue").unwrap(); // Send some data sender.try_send_batch(&[b"a", b"b", b"c", b"d", b"e"]).unwrap(); // Receive exactly 3 elements let batch = receiver.recv_batch(3).await.unwrap(); assert_eq!(batch.len(), 3); assert_eq!(&*batch[0], b"a"); assert_eq!(&*batch[1], b"b"); assert_eq!(&*batch[2], b"c"); // Commit the batch transaction batch.commit().unwrap(); // Receive remaining elements let remaining = receiver.recv_batch(2).await.unwrap(); remaining.commit().unwrap(); }); ``` -------------------------------- ### Receive Data with Timeout in Yaque Source: https://context7.com/tokahuke/yaque/llms.txt Utilize `recv_timeout` with a `Delay` to receive data within a specified time. Returns `None` if the timeout elapses before data is available. Requires `futures_timer` crate. ```rust use yaque::channel; use std::time::Duration; use futures_timer::Delay; futures::executor::block_on(async { let (mut sender, mut receiver) = channel("data/timeout-queue").unwrap(); // Try to receive with 1 second timeout - returns None if nothing available let result = receiver .recv_timeout(Delay::new(Duration::from_secs(1))) .await .unwrap(); assert!(result.is_none()); // Nothing sent yet // Now send something sender.send(b"delayed data").await.unwrap(); // Receive with timeout - should succeed let data = receiver .recv_timeout(Delay::new(Duration::from_secs(1))) .await .unwrap() .expect("should have data"); assert_eq!(&*data, b"delayed data"); data.commit().unwrap(); }); ``` -------------------------------- ### Open Receiver Only Source: https://context7.com/tokahuke/yaque/llms.txt Opens the receiver side of the queue independently to consume data. ```rust use yaque::Receiver; futures::executor::block_on(async { let mut receiver = Receiver::open("data/receive-only-queue").unwrap(); // Receive and process data let data = receiver.recv().await.unwrap(); println!("Received: {:?}", &*data); // Commit to acknowledge processing data.commit().unwrap(); }); ``` -------------------------------- ### Non-blocking Receive with Yaque Source: https://context7.com/tokahuke/yaque/llms.txt The `try_recv` method attempts to receive data without blocking. It returns `Ok(data)` if successful or `Err(TryRecvError::QueueEmpty)` if the queue is empty. ```rust use yaque::{channel, TryRecvError}; let (mut sender, mut receiver) = channel("data/try-recv-queue").unwrap(); // Queue is empty - returns QueueEmpty error match receiver.try_recv() { Ok(_) => panic!("should be empty"), Err(TryRecvError::QueueEmpty) => println!("Queue is empty as expected"), Err(TryRecvError::Io(err)) => panic!("IO error: {}", err), } // Send something sender.try_send(b"available").unwrap(); // Now try_recv succeeds let data = receiver.try_recv().unwrap(); assert_eq!(&*data, b"available"); data.commit().unwrap(); ``` -------------------------------- ### Open Sender Only Source: https://context7.com/tokahuke/yaque/llms.txt Opens the sender side of the queue independently, supporting both synchronous and asynchronous operations. ```rust use yaque::Sender; // Open queue for sending only let mut sender = Sender::open("data/send-only-queue").unwrap(); // Synchronous try_send (non-blocking) sender.try_send(b"message 1").unwrap(); sender.try_send(b"message 2").unwrap(); // Async send (blocks if queue is full when max_queue_size is set) futures::executor::block_on(async { sender.send(b"message 3").await.unwrap(); }); ``` -------------------------------- ### Clear a queue directory Source: https://context7.com/tokahuke/yaque/llms.txt Deletes the queue directory using either synchronous or asynchronous methods. The synchronous version fails if the queue is currently in use. ```rust use yaque::{channel, queue::try_clear, queue::clear}; // Create and use a queue { let (mut sender, mut receiver) = channel("data/clear-queue").unwrap(); sender.try_send(b"data").unwrap(); // sender and receiver dropped here, releasing locks } // Synchronous clear - fails if queue is locked try_clear("data/clear-queue").unwrap(); // Or async clear - waits for queue to be available futures::executor::block_on(async { let (sender, receiver) = channel("data/clear-queue-2").unwrap(); drop(sender); drop(receiver); clear("data/clear-queue-2").await.unwrap(); }); ``` -------------------------------- ### Yaque RecvGuard Transactional Behavior Source: https://context7.com/tokahuke/yaque/llms.txt Demonstrates the transactional nature of `RecvGuard`. Data is only consumed upon explicit `commit()`. Dropping the guard without committing results in a rollback. ```rust use yaque::channel; futures::executor::block_on(async { let (mut sender, mut receiver) = channel("data/transaction-queue").unwrap(); sender.try_send(b"important").unwrap(); // Receive but don't commit - will be rolled back on drop { let data = receiver.recv().await.unwrap(); assert_eq!(&*data, b"important"); // Guard dropped here without commit - data rolls back } // Data is still available after rollback let data = receiver.recv().await.unwrap(); assert_eq!(&*data, b"important"); // Explicit rollback with error handling data.rollback().unwrap(); // Receive and commit permanently let data = receiver.recv().await.unwrap(); data.commit().unwrap(); // Data is now consumed }); ``` -------------------------------- ### Unlock a stale queue Source: https://context7.com/tokahuke/yaque/llms.txt Removes stale lock files left by crashed processes to allow the queue to be reopened. ```rust use yaque::recovery; // Unlock both sender and receiver locks if owning process is dead recovery::unlock_queue("data/stale-queue").unwrap(); // Or unlock individually recovery::unlock_for_sending("data/stale-queue").unwrap(); recovery::unlock_for_receiving("data/stale-queue").unwrap(); // Queue can now be opened let sender = yaque::Sender::open("data/stale-queue").unwrap(); ``` -------------------------------- ### Manually Save Receiver State in Rust Source: https://context7.com/tokahuke/yaque/llms.txt Use the `Receiver::save` method to manually persist the receiver state for crash recovery. This complements automatic save policies. Ensure the receiver is mutable. ```rust use yaque::Receiver; futures::executor::block_on(async { let mut receiver = Receiver::open("data/manual-save-queue").unwrap(); // Process multiple items for _ in 0..100 { if let Ok(data) = receiver.try_recv() { // Process data... data.commit().unwrap(); } } // Explicitly save state for crash recovery receiver.save().unwrap(); }); ``` -------------------------------- ### RecvGuard Transactional Behavior Source: https://context7.com/tokahuke/yaque/llms.txt Provides transactional semantics where data is only removed from the queue when explicitly committed. ```APIDOC ## RecvGuard ### Description Provides transactional semantics - data is only removed from queue when explicitly committed. Dropping without commit triggers rollback. ### Methods - **commit()** - Permanently removes the item from the queue. - **rollback()** - Reverts the transaction, keeping the item in the queue. ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.