mirror of
https://github.com/bspeice/aeron-rs
synced 2024-12-21 21:38:09 -05:00
Merge #4
4: Start the Aeron media driver r=bspeice a=bspeice
Effectively runs the same code as [aeronmd.c](2afd9c6272/aeron-driver/src/main/c/aeronmd.h
), but in Rust.
Note that this just demonstrates how to start the C Media Driver in-process; actual clients communicate through shared memory, so it's expected that actual client code will interface with the C bindings infrequently, if ever. That said, it's not a terrible idea to build more ergonomic bindings into the C layer; when testing the Rust client, we'll need a Media Driver running.
Co-authored-by: Bradlee Speice <bradlee@speice.io>
This commit is contained in:
commit
1889a198b9
@ -6,8 +6,14 @@ edition = "2018"
|
|||||||
repository = "https://github.com/bspeice/aeron-rs"
|
repository = "https://github.com/bspeice/aeron-rs"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
license = "Apache-2.0"
|
license = "Apache-2.0"
|
||||||
|
|
||||||
|
[badges]
|
||||||
travis-ci = { repository = "bspeice/aeron-rs", branch = "master" }
|
travis-ci = { repository = "bspeice/aeron-rs", branch = "master" }
|
||||||
maintenance = { status = "actively-developed" }
|
maintenance = { status = "actively-developed" }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
aeron_driver-sys = { path = "./aeron_driver-sys" }
|
aeron_driver-sys = { path = "./aeron_driver-sys" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
clap = "2.33"
|
||||||
|
ctrlc = "3.1.3"
|
||||||
|
@ -2,4 +2,8 @@
|
|||||||
|
|
||||||
![](https://img.shields.io/travis/bspeice/aeron-rs?style=flat-square)
|
![](https://img.shields.io/travis/bspeice/aeron-rs?style=flat-square)
|
||||||
|
|
||||||
A Rust port of the [Aeron client](https://github.com/real-logic/Aeron).
|
<!-- cargo-sync-readme start -->
|
||||||
|
|
||||||
|
[Aeron](https://github.com/real-logic/aeron) client for Rust
|
||||||
|
|
||||||
|
<!-- cargo-sync-readme end -->
|
||||||
|
@ -1,2 +1,3 @@
|
|||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <aeron_driver_context.h>
|
||||||
#include <aeronmd.h>
|
#include <aeronmd.h>
|
||||||
|
@ -95,6 +95,8 @@ pub fn main() {
|
|||||||
let bindings = bindgen::Builder::default()
|
let bindings = bindgen::Builder::default()
|
||||||
.clang_arg(&format!("-I{}", header_path.display()))
|
.clang_arg(&format!("-I{}", header_path.display()))
|
||||||
.header("bindings.h")
|
.header("bindings.h")
|
||||||
|
.whitelist_function("aeron_.*")
|
||||||
|
.whitelist_type("aeron_.*")
|
||||||
.generate()
|
.generate()
|
||||||
.expect("Unable to generate aeron_driver bindings");
|
.expect("Unable to generate aeron_driver bindings");
|
||||||
|
|
||||||
|
96
examples/aeronmd.rs
Normal file
96
examples/aeronmd.rs
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
//! Media driver startup example based on
|
||||||
|
//! [aeronmd.c](https://github.com/real-logic/aeron/blob/master/aeron-driver/src/main/c/aeronmd.c)
|
||||||
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
use aeron_driver_sys::*;
|
||||||
|
use clap;
|
||||||
|
use ctrlc;
|
||||||
|
use std::ffi::CStr;
|
||||||
|
use std::os::raw::c_void;
|
||||||
|
use std::ptr;
|
||||||
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
|
|
||||||
|
static RUNNING: AtomicBool = AtomicBool::new(true);
|
||||||
|
|
||||||
|
unsafe extern "C" fn termination_hook(_clientd: *mut c_void) {
|
||||||
|
RUNNING.store(false, Ordering::SeqCst);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let version = unsafe { CStr::from_ptr(aeron_version_full()) };
|
||||||
|
let _cmdline = clap::App::new("aeronmd")
|
||||||
|
.version(version.to_str().unwrap())
|
||||||
|
.get_matches();
|
||||||
|
|
||||||
|
// TODO: Handle -D switches
|
||||||
|
|
||||||
|
ctrlc::set_handler(move || {
|
||||||
|
// TODO: Actually understand atomic ordering
|
||||||
|
RUNNING.store(false, Ordering::SeqCst);
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let mut init_success = true;
|
||||||
|
let mut context: *mut aeron_driver_context_t = ptr::null_mut();
|
||||||
|
let mut driver: *mut aeron_driver_t = ptr::null_mut();
|
||||||
|
|
||||||
|
if init_success {
|
||||||
|
let context_init = unsafe { aeron_driver_context_init(&mut context) };
|
||||||
|
if context_init < 0 {
|
||||||
|
let err_code = unsafe { aeron_errcode() };
|
||||||
|
let err_str = unsafe { CStr::from_ptr(aeron_errmsg()) }.to_str().unwrap();
|
||||||
|
eprintln!("ERROR: context init ({}) {}", err_code, err_str);
|
||||||
|
init_success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if init_success {
|
||||||
|
let term_hook = unsafe {
|
||||||
|
aeron_driver_context_set_driver_termination_hook(
|
||||||
|
context,
|
||||||
|
Some(termination_hook),
|
||||||
|
ptr::null_mut(),
|
||||||
|
)
|
||||||
|
};
|
||||||
|
if term_hook < 0 {
|
||||||
|
let err_code = unsafe { aeron_errcode() };
|
||||||
|
let err_str = unsafe { CStr::from_ptr(aeron_errmsg()) }.to_str().unwrap();
|
||||||
|
eprintln!(
|
||||||
|
"ERROR: context set termination hook ({}) {}",
|
||||||
|
err_code, err_str
|
||||||
|
);
|
||||||
|
init_success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if init_success {
|
||||||
|
let driver_init = unsafe { aeron_driver_init(&mut driver, context) };
|
||||||
|
if driver_init < 0 {
|
||||||
|
let err_code = unsafe { aeron_errcode() };
|
||||||
|
let err_str = unsafe { CStr::from_ptr(aeron_errmsg()) }.to_str().unwrap();
|
||||||
|
eprintln!("ERROR: driver init ({}) {}", err_code, err_str);
|
||||||
|
init_success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if init_success {
|
||||||
|
let driver_start = unsafe { aeron_driver_start(driver, true) };
|
||||||
|
if driver_start < 0 {
|
||||||
|
let err_code = unsafe { aeron_errcode() };
|
||||||
|
let err_str = unsafe { CStr::from_ptr(aeron_errmsg()) }.to_str().unwrap();
|
||||||
|
eprintln!("ERROR: driver start ({}) {}", err_code, err_str);
|
||||||
|
init_success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if init_success {
|
||||||
|
println!("Press Ctrl-C to exit.");
|
||||||
|
|
||||||
|
while RUNNING.load(Ordering::SeqCst) {
|
||||||
|
unsafe { aeron_driver_main_idle_strategy(driver, aeron_driver_main_do_work(driver)) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe { aeron_driver_close(driver) };
|
||||||
|
unsafe { aeron_driver_context_close(context) };
|
||||||
|
}
|
44
src/context.rs
Normal file
44
src/context.rs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
use std::env;
|
||||||
|
use std::path::PathBuf;
|
||||||
|
|
||||||
|
const DEFAULT_MEDIA_DRIVER_TIMEOUT_MS: u16 = 10_000;
|
||||||
|
const DEFAULT_RESOURCE_LINGER_MS: u16 = 5_000;
|
||||||
|
|
||||||
|
pub struct Context {
|
||||||
|
aeron_dir: PathBuf,
|
||||||
|
media_driver_timeout_ms: i32,
|
||||||
|
resource_linger_timeout_ms: i32,
|
||||||
|
use_conductor_agent_invoker: bool,
|
||||||
|
pre_touch_mapped_memory: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Context {
|
||||||
|
pub fn get_user_name() -> String {
|
||||||
|
env::var("USER")
|
||||||
|
.or_else(|_| env::var("USERNAME"))
|
||||||
|
.unwrap_or("default".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn default_aeron_path() -> PathBuf {
|
||||||
|
let base_path = if cfg!(target_os = "linux") {
|
||||||
|
PathBuf::from("/dev/shm")
|
||||||
|
} else {
|
||||||
|
// Uses TMPDIR on Unix-like, and GetTempPath on Windows
|
||||||
|
env::temp_dir()
|
||||||
|
};
|
||||||
|
|
||||||
|
base_path.join(format!("aeron-{}", Context::get_user_name()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Context {
|
||||||
|
fn default() -> Self {
|
||||||
|
Context {
|
||||||
|
aeron_dir: Context::default_aeron_path(),
|
||||||
|
media_driver_timeout_ms: DEFAULT_MEDIA_DRIVER_TIMEOUT_MS.into(),
|
||||||
|
resource_linger_timeout_ms: DEFAULT_RESOURCE_LINGER_MS.into(),
|
||||||
|
use_conductor_agent_invoker: false,
|
||||||
|
pre_touch_mapped_memory: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
//! Aeron client for Rust
|
//! [Aeron](https://github.com/real-logic/aeron) client for Rust
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
|
mod context;
|
||||||
|
|
||||||
/// Retrieve the C library version in (major, minor, patch) format
|
/// Retrieve the C library version in (major, minor, patch) format
|
||||||
pub fn aeron_version() -> (u32, u32, u32) {
|
pub fn aeron_version() -> (u32, u32, u32) {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
Loading…
Reference in New Issue
Block a user