feat: rework config to use builder pattern
This commit is contained in:
parent
f561c4e9c5
commit
a8aa0f8bf7
@ -4,6 +4,7 @@ use std::time::Duration;
|
||||
|
||||
use jni::objects::GlobalRef;
|
||||
use no_std_net::SocketAddr;
|
||||
use toad::config::Config;
|
||||
use toad::net::Addrd;
|
||||
use toad::platform::Platform;
|
||||
use toad_jni::java::lang::System;
|
||||
@ -28,7 +29,7 @@ fn init() -> State {
|
||||
let mut _env = crate::test::init();
|
||||
let env = &mut _env;
|
||||
|
||||
let cfg = RuntimeConfig::new(env);
|
||||
let cfg = RuntimeConfig::new(env, Config::default(), 5683);
|
||||
let runtime = Runtime::get_or_init(env, cfg);
|
||||
let client = crate::Runtime::try_new("0.0.0.0:5684", Default::default()).unwrap();
|
||||
|
||||
|
@ -45,6 +45,7 @@ pub mod test {
|
||||
use std::sync::Once;
|
||||
|
||||
use jni::{InitArgsBuilder, JavaVM};
|
||||
use toad::config::Config;
|
||||
use toad::retry::Strategy;
|
||||
use toad::time::Millis;
|
||||
use toad_jni::java;
|
||||
@ -80,8 +81,8 @@ pub mod test {
|
||||
let mut e = init();
|
||||
let e = &mut e;
|
||||
|
||||
let r = RuntimeConfig::new(e);
|
||||
assert_eq!(r.to_toad(e), Default::default());
|
||||
let r = RuntimeConfig::new(e, Config::default(), 5683);
|
||||
assert_eq!(r.to_toad(e), Config::default());
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
@ -53,7 +53,9 @@ struct Mem {
|
||||
pub struct GlobalStatic;
|
||||
impl SharedMemoryRegion for GlobalStatic {
|
||||
unsafe fn dealloc() {
|
||||
drop(Box::from_raw(MEM));
|
||||
if !MEM.is_null() {
|
||||
drop(Box::from_raw(MEM));
|
||||
}
|
||||
}
|
||||
|
||||
unsafe fn init(r: impl FnOnce() -> crate::Runtime) -> *mut crate::Runtime {
|
||||
|
@ -36,8 +36,7 @@ impl Runtime {
|
||||
}
|
||||
|
||||
fn init_impl(e: &mut java::Env, cfg: RuntimeConfig) -> i64 {
|
||||
let r =
|
||||
|| ToadRuntime::try_new(format!("0.0.0.0:{}", cfg.net(e).port(e)), cfg.to_toad(e)).unwrap();
|
||||
let r = || ToadRuntime::try_new(format!("0.0.0.0:{}", cfg.port(e)), cfg.to_toad(e)).unwrap();
|
||||
unsafe { crate::mem::Shared::init(r).addr() as i64 }
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
use toad::config::{self, BytesPerSecond};
|
||||
use jni::objects::JClass;
|
||||
use jni::sys::jobject;
|
||||
use toad::config::{self, BytesPerSecond, Config};
|
||||
use toad::retry::{Attempts, Strategy};
|
||||
use toad::time::Millis;
|
||||
use toad_jni::java;
|
||||
use toad_jni::java::{self, Class, Object};
|
||||
|
||||
use crate::retry_strategy::RetryStrategy;
|
||||
use crate::uint;
|
||||
@ -10,91 +12,69 @@ pub struct RuntimeConfig(java::lang::Object);
|
||||
|
||||
java::object_newtype!(RuntimeConfig);
|
||||
impl java::Class for RuntimeConfig {
|
||||
const PATH: &'static str = package!(dev.toad.RuntimeOptions);
|
||||
const PATH: &'static str = concat!(package!(dev.toad.Runtime), "$Config");
|
||||
}
|
||||
|
||||
impl RuntimeConfig {
|
||||
pub fn new(e: &mut java::Env) -> Self {
|
||||
static CTOR: java::Constructor<RuntimeConfig, fn()> = java::Constructor::new();
|
||||
CTOR.invoke(e)
|
||||
}
|
||||
|
||||
pub fn net(&self, e: &mut java::Env) -> Net {
|
||||
static NET: java::Method<RuntimeConfig, fn() -> Net> = java::Method::new("net");
|
||||
NET.invoke(e, self)
|
||||
}
|
||||
|
||||
pub fn to_toad(&self, e: &mut java::Env) -> config::Config {
|
||||
let def = config::Config::default();
|
||||
|
||||
let net = self.net(e);
|
||||
let msg = net.msg(e);
|
||||
let con = msg.con(e);
|
||||
let non = msg.non(e);
|
||||
|
||||
config::Config { max_concurrent_requests: net.concurrency(e) as u8,
|
||||
msg: config::Msg { token_seed: msg.token_seed(e)
|
||||
.map(|i| i as u16)
|
||||
.unwrap_or(def.msg.token_seed),
|
||||
probing_rate: msg.probing_rate(e)
|
||||
.map(|i| BytesPerSecond(i as u16))
|
||||
.unwrap_or(def.msg.probing_rate),
|
||||
multicast_response_leisure:
|
||||
msg.multicast_response_leisure(e)
|
||||
.unwrap_or(def.msg.multicast_response_leisure),
|
||||
con:
|
||||
config::Con { unacked_retry_strategy:
|
||||
con.unacked_retry_strategy(e)
|
||||
.unwrap_or(def.msg
|
||||
.con
|
||||
.unacked_retry_strategy),
|
||||
acked_retry_strategy:
|
||||
con.acked_retry_strategy(e)
|
||||
.unwrap_or(def.msg
|
||||
.con
|
||||
.acked_retry_strategy),
|
||||
max_attempts:
|
||||
con.max_attempts(e)
|
||||
.map(|i| Attempts(i as u16))
|
||||
.unwrap_or(def.msg.con.max_attempts) },
|
||||
non: config::Non { retry_strategy:
|
||||
non.retry_strategy(e)
|
||||
.unwrap_or(def.msg
|
||||
.non
|
||||
.retry_strategy),
|
||||
max_attempts:
|
||||
non.max_attempts(e)
|
||||
.map(|i| Attempts(i as u16))
|
||||
.unwrap_or(def.msg.non.max_attempts) } } }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Net(java::lang::Object);
|
||||
java::object_newtype!(Net);
|
||||
impl java::Class for Net {
|
||||
const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Net");
|
||||
}
|
||||
|
||||
static NET_PORT: java::Field<Net, uint::u16> = java::Field::new("port");
|
||||
|
||||
impl Net {
|
||||
pub fn port(&self, e: &mut java::Env) -> u16 {
|
||||
NET_PORT.get(e, self).to_rust(e)
|
||||
}
|
||||
|
||||
pub fn set_port(&self, e: &mut java::Env, new: u16) {
|
||||
let new = uint::u16::from_rust(e, new);
|
||||
NET_PORT.set(e, self, new)
|
||||
static RUNTIME_CONFIG_PORT: java::Field<RuntimeConfig, uint::u16> = java::Field::new("port");
|
||||
RUNTIME_CONFIG_PORT.get(e, self).to_rust(e)
|
||||
}
|
||||
|
||||
pub fn concurrency(&self, e: &mut java::Env) -> u8 {
|
||||
static CONCURRENCY: java::Field<Net, uint::u8> = java::Field::new("concurrency");
|
||||
CONCURRENCY.get(e, self).to_rust(e)
|
||||
static RUNTIME_CONFIG_CONCURRENCY: java::Field<RuntimeConfig, uint::u8> =
|
||||
java::Field::new("concurrency");
|
||||
RUNTIME_CONFIG_CONCURRENCY.get(e, self).to_rust(e)
|
||||
}
|
||||
|
||||
pub fn msg(&self, e: &mut java::Env) -> Msg {
|
||||
static MSG: java::Method<Net, fn() -> Msg> = java::Method::new("msg");
|
||||
MSG.invoke(e, self)
|
||||
static RUNTIME_CONFIG_MSG: java::Method<RuntimeConfig, fn() -> Msg> = java::Method::new("msg");
|
||||
RUNTIME_CONFIG_MSG.invoke(e, self)
|
||||
}
|
||||
|
||||
pub fn new(e: &mut java::Env, c: Config, port: u16) -> Self {
|
||||
static CTOR: java::Constructor<RuntimeConfig, fn(uint::u16, uint::u8, Msg)> =
|
||||
java::Constructor::new();
|
||||
|
||||
let con = Con::new(e,
|
||||
c.msg.con.unacked_retry_strategy,
|
||||
c.msg.con.acked_retry_strategy,
|
||||
c.msg.con.max_attempts);
|
||||
let non = Non::new(e, c.msg.non.retry_strategy, c.msg.non.max_attempts);
|
||||
let msg = Msg::new(e,
|
||||
c.msg.token_seed,
|
||||
c.msg.probing_rate.0,
|
||||
c.msg.multicast_response_leisure,
|
||||
con,
|
||||
non);
|
||||
|
||||
let port = uint::u16::from_rust(e, port);
|
||||
let concurrency = uint::u8::from_rust(e, c.max_concurrent_requests);
|
||||
|
||||
let jcfg = CTOR.invoke(e, port, concurrency, msg);
|
||||
jcfg
|
||||
}
|
||||
|
||||
pub fn to_toad(&self, e: &mut java::Env) -> config::Config {
|
||||
let msg = self.msg(e);
|
||||
let con = msg.con(e);
|
||||
let non = msg.non(e);
|
||||
|
||||
config::Config { max_concurrent_requests: self.concurrency(e) as u8,
|
||||
msg: config::Msg { token_seed: msg.token_seed(e) as _,
|
||||
probing_rate: BytesPerSecond(msg.probing_rate(e) as _),
|
||||
multicast_response_leisure:
|
||||
msg.multicast_response_leisure(e),
|
||||
con: config::Con { unacked_retry_strategy:
|
||||
con.unacked_retry_strategy(e),
|
||||
acked_retry_strategy:
|
||||
con.acked_retry_strategy(e),
|
||||
max_attempts:
|
||||
Attempts(con.max_attempts(e) as _) },
|
||||
non: config::Non { retry_strategy:
|
||||
non.retry_strategy(e),
|
||||
max_attempts:
|
||||
Attempts(non.max_attempts(e) as _) } } }
|
||||
}
|
||||
}
|
||||
|
||||
@ -103,30 +83,49 @@ pub struct Msg(java::lang::Object);
|
||||
java::object_newtype!(Msg);
|
||||
|
||||
impl java::Class for Msg {
|
||||
const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Msg");
|
||||
const PATH: &'static str = concat!(package!(dev.toad.Runtime), "$Config$Msg");
|
||||
}
|
||||
|
||||
impl Msg {
|
||||
pub fn token_seed(&self, e: &mut java::Env) -> Option<i32> {
|
||||
static TOKEN_SEED: java::Method<Msg, fn() -> java::util::Optional<i32>> =
|
||||
java::Method::new("tokenSeed");
|
||||
TOKEN_SEED.invoke(e, self).to_option(e)
|
||||
pub fn new(e: &mut java::Env,
|
||||
token_seed: u16,
|
||||
probe_rate: u16,
|
||||
multicast_response_leisure: Millis,
|
||||
con: Con,
|
||||
non: Non)
|
||||
-> Self {
|
||||
static CTOR: java::Constructor<Msg, fn(uint::u16, uint::u16, java::time::Duration, Con, Non)> =
|
||||
java::Constructor::new();
|
||||
let token_seed = uint::u16::from_rust(e, token_seed);
|
||||
let probe_rate = uint::u16::from_rust(e, probe_rate);
|
||||
let multicast_response_leisure =
|
||||
java::time::Duration::of_millis(e, multicast_response_leisure.0 as i64);
|
||||
|
||||
CTOR.invoke(e,
|
||||
token_seed,
|
||||
probe_rate,
|
||||
multicast_response_leisure,
|
||||
con,
|
||||
non)
|
||||
}
|
||||
|
||||
pub fn probing_rate(&self, e: &mut java::Env) -> Option<i32> {
|
||||
static PROBING_RATE: java::Method<Msg, fn() -> java::util::Optional<i32>> =
|
||||
pub fn token_seed(&self, e: &mut java::Env) -> i32 {
|
||||
static TOKEN_SEED: java::Method<Msg, fn() -> i32> = java::Method::new("tokenSeed");
|
||||
TOKEN_SEED.invoke(e, self)
|
||||
}
|
||||
|
||||
pub fn probing_rate(&self, e: &mut java::Env) -> i32 {
|
||||
static PROBING_RATE: java::Method<Msg, fn() -> i32> =
|
||||
java::Method::new("probingRateBytesPerSecond");
|
||||
PROBING_RATE.invoke(e, self).to_option(e)
|
||||
PROBING_RATE.invoke(e, self)
|
||||
}
|
||||
|
||||
pub fn multicast_response_leisure(&self, e: &mut java::Env) -> Option<Millis> {
|
||||
static MULTICAST_RESP_LEISURE: java::Method<Msg,
|
||||
fn()
|
||||
-> java::util::Optional<java::time::Duration>> =
|
||||
pub fn multicast_response_leisure(&self, e: &mut java::Env) -> Millis {
|
||||
static MULTICAST_RESP_LEISURE: java::Method<Msg, fn() -> java::time::Duration> =
|
||||
java::Method::new("multicastResponseLeisure");
|
||||
MULTICAST_RESP_LEISURE.invoke(e, self)
|
||||
.to_option(e)
|
||||
.map(|d| Millis::new(d.to_millis(e) as u64))
|
||||
let d = MULTICAST_RESP_LEISURE.invoke(e, self);
|
||||
|
||||
Millis::new(d.to_millis(e) as u64)
|
||||
}
|
||||
|
||||
pub fn con(&self, e: &mut java::Env) -> Con {
|
||||
@ -144,30 +143,38 @@ pub struct Con(java::lang::Object);
|
||||
|
||||
java::object_newtype!(Con);
|
||||
impl java::Class for Con {
|
||||
const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Msg$Con");
|
||||
const PATH: &'static str = concat!(package!(dev.toad.Runtime), "$Config$Msg$Con");
|
||||
}
|
||||
|
||||
impl Con {
|
||||
pub fn acked_retry_strategy(&self, e: &mut java::Env) -> Option<Strategy> {
|
||||
static ACKED_RETRY_STRATEGY: java::Method<Con, fn() -> java::util::Optional<RetryStrategy>> =
|
||||
pub fn new(e: &mut java::Env,
|
||||
unacked: toad::retry::Strategy,
|
||||
acked: toad::retry::Strategy,
|
||||
max_attempts: Attempts)
|
||||
-> Self {
|
||||
static CTOR: java::Constructor<Con, fn(RetryStrategy, RetryStrategy, uint::u16)> =
|
||||
java::Constructor::new();
|
||||
let unacked = RetryStrategy::from_toad(e, unacked);
|
||||
let acked = RetryStrategy::from_toad(e, acked);
|
||||
let att = uint::u16::from_rust(e, max_attempts.0);
|
||||
CTOR.invoke(e, unacked, acked, att)
|
||||
}
|
||||
|
||||
pub fn acked_retry_strategy(&self, e: &mut java::Env) -> Strategy {
|
||||
static ACKED_RETRY_STRATEGY: java::Method<Con, fn() -> RetryStrategy> =
|
||||
java::Method::new("ackedRetryStrategy");
|
||||
ACKED_RETRY_STRATEGY.invoke(e, self)
|
||||
.to_option(e)
|
||||
.map(|s| s.to_toad(e))
|
||||
ACKED_RETRY_STRATEGY.invoke(e, self).to_toad(e)
|
||||
}
|
||||
|
||||
pub fn unacked_retry_strategy(&self, e: &mut java::Env) -> Option<Strategy> {
|
||||
static UNACKED_RETRY_STRATEGY: java::Method<Con, fn() -> java::util::Optional<RetryStrategy>> =
|
||||
pub fn unacked_retry_strategy(&self, e: &mut java::Env) -> Strategy {
|
||||
static UNACKED_RETRY_STRATEGY: java::Method<Con, fn() -> RetryStrategy> =
|
||||
java::Method::new("unackedRetryStrategy");
|
||||
UNACKED_RETRY_STRATEGY.invoke(e, self)
|
||||
.to_option(e)
|
||||
.map(|s| s.to_toad(e))
|
||||
UNACKED_RETRY_STRATEGY.invoke(e, self).to_toad(e)
|
||||
}
|
||||
|
||||
pub fn max_attempts(&self, e: &mut java::Env) -> Option<i32> {
|
||||
static MAX_ATTEMPTS: java::Method<Con, fn() -> java::util::Optional<i32>> =
|
||||
java::Method::new("maxAttempts");
|
||||
MAX_ATTEMPTS.invoke(e, self).to_option(e)
|
||||
pub fn max_attempts(&self, e: &mut java::Env) -> i32 {
|
||||
static MAX_ATTEMPTS: java::Method<Con, fn() -> i32> = java::Method::new("maxAttempts");
|
||||
MAX_ATTEMPTS.invoke(e, self)
|
||||
}
|
||||
}
|
||||
|
||||
@ -175,21 +182,32 @@ pub struct Non(java::lang::Object);
|
||||
|
||||
java::object_newtype!(Non);
|
||||
impl java::Class for Non {
|
||||
const PATH: &'static str = concat!(package!(dev.toad.RuntimeOptions), "$Msg$Non");
|
||||
const PATH: &'static str = concat!(package!(dev.toad.Runtime), "$Config$Msg$Non");
|
||||
}
|
||||
|
||||
impl Non {
|
||||
pub fn retry_strategy(&self, e: &mut java::Env) -> Option<Strategy> {
|
||||
static RETRY_STRATEGY: java::Method<Non, fn() -> java::util::Optional<RetryStrategy>> =
|
||||
java::Method::new("retryStrategy");
|
||||
RETRY_STRATEGY.invoke(e, self)
|
||||
.to_option(e)
|
||||
.map(|s| s.to_toad(e))
|
||||
pub fn new(e: &mut java::Env, strat: toad::retry::Strategy, max_attempts: Attempts) -> Self {
|
||||
static CTOR: java::Constructor<Non, fn(RetryStrategy, uint::u16)> = java::Constructor::new();
|
||||
let strat = RetryStrategy::from_toad(e, strat);
|
||||
let att = uint::u16::from_rust(e, max_attempts.0);
|
||||
CTOR.invoke(e, strat, att)
|
||||
}
|
||||
|
||||
pub fn max_attempts(&self, e: &mut java::Env) -> Option<i32> {
|
||||
static MAX_ATTEMPTS: java::Method<Non, fn() -> java::util::Optional<i32>> =
|
||||
java::Method::new("maxAttempts");
|
||||
MAX_ATTEMPTS.invoke(e, self).to_option(e)
|
||||
pub fn retry_strategy(&self, e: &mut java::Env) -> Strategy {
|
||||
static RETRY_STRATEGY: java::Method<Non, fn() -> RetryStrategy> =
|
||||
java::Method::new("retryStrategy");
|
||||
RETRY_STRATEGY.invoke(e, self).to_toad(e)
|
||||
}
|
||||
|
||||
pub fn max_attempts(&self, e: &mut java::Env) -> i32 {
|
||||
static MAX_ATTEMPTS: java::Method<Non, fn() -> i32> = java::Method::new("maxAttempts");
|
||||
MAX_ATTEMPTS.invoke(e, self)
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "system" fn Java_dev_toad_Runtime_defaultConfigImpl<'local>(mut env: java::Env<'local>,
|
||||
_: JClass<'local>)
|
||||
-> jobject {
|
||||
RuntimeConfig::new(&mut env, Config::default(), 5683).yield_to_java(&mut env)
|
||||
}
|
||||
|
@ -1,24 +1,340 @@
|
||||
package dev.toad;
|
||||
|
||||
import dev.toad.ffi.*;
|
||||
import dev.toad.msg.MessageRef;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
|
||||
interface BuilderPort {
|
||||
Runtime.Config.Builder port(short port);
|
||||
}
|
||||
|
||||
public class Runtime {
|
||||
|
||||
protected static native Config defaultConfigImpl();
|
||||
|
||||
protected static Config defaultConfig = null;
|
||||
|
||||
protected static Config defaultConfig() {
|
||||
if (Runtime.defaultConfig == null) {
|
||||
Runtime.defaultConfig = Runtime.defaultConfigImpl();
|
||||
}
|
||||
|
||||
return Runtime.defaultConfig;
|
||||
}
|
||||
|
||||
static {
|
||||
System.loadLibrary("toad_java_glue");
|
||||
}
|
||||
|
||||
private final long addr;
|
||||
|
||||
private static native long init(RuntimeOptions o);
|
||||
private static native long init(Config o);
|
||||
|
||||
private native Optional<MessageRef> pollReq();
|
||||
|
||||
public static Runtime getOrInit(RuntimeOptions o) {
|
||||
public static Runtime getOrInit(Config o) {
|
||||
return new Runtime(o);
|
||||
}
|
||||
|
||||
public Runtime(RuntimeOptions o) {
|
||||
public Runtime(Config o) {
|
||||
this.addr = Runtime.init(o);
|
||||
}
|
||||
|
||||
public static final class Config {
|
||||
|
||||
protected u16 port;
|
||||
protected u8 concurrency;
|
||||
protected Msg msg;
|
||||
|
||||
protected Config(u16 port, u8 concurrency, Msg msg) {
|
||||
this.port = port;
|
||||
this.concurrency = concurrency;
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return switch (other) {
|
||||
case Config o -> o.port == this.port &&
|
||||
o.concurrency == this.concurrency &&
|
||||
o.msg == this.msg;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
public int port() {
|
||||
return this.port.intValue();
|
||||
}
|
||||
|
||||
public short concurrency() {
|
||||
return this.concurrency.shortValue();
|
||||
}
|
||||
|
||||
public Msg msg() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
public static final class Builder implements BuilderPort {
|
||||
|
||||
public final Msg.Builder msg = Msg.builder();
|
||||
|
||||
protected Optional<u16> port = Optional.empty();
|
||||
protected u8 concurrency = Runtime.defaultConfig().concurrency;
|
||||
|
||||
protected Builder() {}
|
||||
|
||||
public Config build() {
|
||||
return new Config(this.port.get(), this.concurrency, this.msg.build());
|
||||
}
|
||||
|
||||
public Builder port(short port) {
|
||||
this.port = Optional.of(new u16(port));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder concurrency(byte concurrency) {
|
||||
this.concurrency = new u8(concurrency);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Msg {
|
||||
|
||||
protected u16 tokenSeed;
|
||||
protected u16 probingRateBytesPerSecond;
|
||||
protected Duration multicastResponseLeisure;
|
||||
protected Con con;
|
||||
protected Non non;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
protected Msg(
|
||||
u16 tokenSeed,
|
||||
u16 probingRateBytesPerSecond,
|
||||
Duration multicastResponseLeisure,
|
||||
Con con,
|
||||
Non non
|
||||
) {
|
||||
this.tokenSeed = tokenSeed;
|
||||
this.probingRateBytesPerSecond = probingRateBytesPerSecond;
|
||||
this.multicastResponseLeisure = multicastResponseLeisure;
|
||||
this.con = con;
|
||||
this.non = non;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return switch (other) {
|
||||
case Msg o -> o.tokenSeed == this.tokenSeed &&
|
||||
o.probingRateBytesPerSecond == this.probingRateBytesPerSecond &&
|
||||
o.multicastResponseLeisure == this.multicastResponseLeisure &&
|
||||
o.con == this.con &&
|
||||
o.non == this.non;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
public int tokenSeed() {
|
||||
return this.tokenSeed.intValue();
|
||||
}
|
||||
|
||||
public int probingRateBytesPerSecond() {
|
||||
return this.probingRateBytesPerSecond.intValue();
|
||||
}
|
||||
|
||||
public Duration multicastResponseLeisure() {
|
||||
return this.multicastResponseLeisure;
|
||||
}
|
||||
|
||||
public Con con() {
|
||||
return this.con;
|
||||
}
|
||||
|
||||
public Non non() {
|
||||
return this.non;
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
public final Con.Builder con = Con.builder();
|
||||
public final Non.Builder non = Non.builder();
|
||||
|
||||
protected u16 tokenSeed = Runtime.defaultConfig().msg.tokenSeed;
|
||||
protected u16 probingRateBytesPerSecond = Runtime.defaultConfig()
|
||||
.msg.probingRateBytesPerSecond;
|
||||
protected Duration multicastResponseLeisure = Runtime.defaultConfig()
|
||||
.msg.multicastResponseLeisure;
|
||||
|
||||
public Msg build() {
|
||||
return new Msg(
|
||||
this.tokenSeed,
|
||||
this.probingRateBytesPerSecond,
|
||||
this.multicastResponseLeisure,
|
||||
this.con.build(),
|
||||
this.non.build()
|
||||
);
|
||||
}
|
||||
|
||||
public Builder tokenSeed(u16 tokenSeed) {
|
||||
this.tokenSeed = tokenSeed;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder probingRateBytesPerSecond(
|
||||
u16 probingRateBytesPerSecond
|
||||
) {
|
||||
this.probingRateBytesPerSecond = probingRateBytesPerSecond;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder multicastResponseLeisure(
|
||||
Duration multicastResponseLeisure
|
||||
) {
|
||||
this.multicastResponseLeisure = multicastResponseLeisure;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Builder() {}
|
||||
}
|
||||
|
||||
public static final class Con {
|
||||
|
||||
protected RetryStrategy ackedRetryStrategy;
|
||||
protected RetryStrategy unackedRetryStrategy;
|
||||
protected u16 maxAttempts;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
protected Con(
|
||||
RetryStrategy unackedRetryStrategy,
|
||||
RetryStrategy ackedRetryStrategy,
|
||||
u16 maxAttempts
|
||||
) {
|
||||
this.unackedRetryStrategy = unackedRetryStrategy;
|
||||
this.ackedRetryStrategy = ackedRetryStrategy;
|
||||
this.maxAttempts = maxAttempts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return switch (other) {
|
||||
case Con o -> this.ackedRetryStrategy == o.ackedRetryStrategy &&
|
||||
this.unackedRetryStrategy == o.unackedRetryStrategy &&
|
||||
this.maxAttempts == o.maxAttempts;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
public RetryStrategy ackedRetryStrategy() {
|
||||
return this.ackedRetryStrategy;
|
||||
}
|
||||
|
||||
public RetryStrategy unackedRetryStrategy() {
|
||||
return this.unackedRetryStrategy;
|
||||
}
|
||||
|
||||
public int maxAttempts() {
|
||||
return this.maxAttempts.intValue();
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
protected RetryStrategy ackedRetryStrategy = Runtime.defaultConfig()
|
||||
.msg.con.ackedRetryStrategy;
|
||||
protected RetryStrategy unackedRetryStrategy = Runtime.defaultConfig()
|
||||
.msg.con.unackedRetryStrategy;
|
||||
protected u16 maxAttempts = Runtime.defaultConfig()
|
||||
.msg.con.maxAttempts;
|
||||
|
||||
public Con build() {
|
||||
return new Con(
|
||||
this.unackedRetryStrategy,
|
||||
this.ackedRetryStrategy,
|
||||
this.maxAttempts
|
||||
);
|
||||
}
|
||||
|
||||
public Builder ackedRetryStrategy(RetryStrategy ackedRetryStrategy) {
|
||||
this.ackedRetryStrategy = ackedRetryStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder unackedRetryStrategy(
|
||||
RetryStrategy unackedRetryStrategy
|
||||
) {
|
||||
this.unackedRetryStrategy = unackedRetryStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder maxAttempts(u16 maxAttempts) {
|
||||
this.maxAttempts = maxAttempts;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Builder() {}
|
||||
}
|
||||
}
|
||||
|
||||
public static final class Non {
|
||||
|
||||
protected RetryStrategy retryStrategy;
|
||||
protected u16 maxAttempts;
|
||||
|
||||
public static Builder builder() {
|
||||
return new Builder();
|
||||
}
|
||||
|
||||
protected Non(RetryStrategy retryStrategy, u16 maxAttempts) {
|
||||
this.retryStrategy = retryStrategy;
|
||||
this.maxAttempts = maxAttempts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return switch (other) {
|
||||
case Non o -> this.retryStrategy == o.retryStrategy &&
|
||||
this.maxAttempts == o.maxAttempts;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
public RetryStrategy retryStrategy() {
|
||||
return this.retryStrategy;
|
||||
}
|
||||
|
||||
public int maxAttempts() {
|
||||
return this.maxAttempts.intValue();
|
||||
}
|
||||
|
||||
public static final class Builder {
|
||||
|
||||
protected RetryStrategy retryStrategy = Runtime.defaultConfig()
|
||||
.msg.non.retryStrategy;
|
||||
protected u16 maxAttempts = Runtime.defaultConfig()
|
||||
.msg.non.maxAttempts;
|
||||
|
||||
public Non build() {
|
||||
return new Non(this.retryStrategy, this.maxAttempts);
|
||||
}
|
||||
|
||||
public Builder retryStrategy(RetryStrategy retryStrategy) {
|
||||
this.retryStrategy = retryStrategy;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder maxAttempts(u16 maxAttempts) {
|
||||
this.maxAttempts = maxAttempts;
|
||||
return this;
|
||||
}
|
||||
|
||||
protected Builder() {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,319 +0,0 @@
|
||||
package dev.toad;
|
||||
|
||||
import dev.toad.ffi.*;
|
||||
import java.time.Duration;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Function;
|
||||
|
||||
public final class RuntimeOptions implements Cloneable {
|
||||
|
||||
private Net net;
|
||||
|
||||
public RuntimeOptions() {
|
||||
this.net = new Net();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return switch (other) {
|
||||
case RuntimeOptions o -> o.net == this.net;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
public Net net() {
|
||||
return this.net;
|
||||
}
|
||||
|
||||
private RuntimeOptions with(Function<RuntimeOptions, RuntimeOptions> f) {
|
||||
return f.apply(this.clone());
|
||||
}
|
||||
|
||||
public RuntimeOptions withNet(Function<Net, Net> f) {
|
||||
return this.with(self -> {
|
||||
self.net = f.apply(self.net);
|
||||
return self;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public RuntimeOptions clone() {
|
||||
RuntimeOptions self = new RuntimeOptions();
|
||||
self.net = this.net.clone();
|
||||
return self;
|
||||
}
|
||||
|
||||
public final class Net implements Cloneable {
|
||||
|
||||
private u16 port;
|
||||
private u8 concurrency;
|
||||
private Msg msg;
|
||||
|
||||
public Net() {
|
||||
this.port = new u16(5683);
|
||||
this.concurrency = new u8((short) 1);
|
||||
this.msg = new Msg();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return switch (other) {
|
||||
case Net o -> o.port == this.port &&
|
||||
o.concurrency == this.concurrency &&
|
||||
o.msg == this.msg;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private Net with(Function<Net, Net> f) {
|
||||
return f.apply(this.clone());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Net clone() {
|
||||
Net self = new Net();
|
||||
self.port = this.port;
|
||||
self.concurrency = this.concurrency;
|
||||
self.msg = this.msg.clone();
|
||||
return self;
|
||||
}
|
||||
|
||||
public int port() {
|
||||
return this.port.intValue();
|
||||
}
|
||||
|
||||
public short concurrency() {
|
||||
return this.concurrency.shortValue();
|
||||
}
|
||||
|
||||
public Msg msg() {
|
||||
return this.msg;
|
||||
}
|
||||
|
||||
public Net withPort(short port) {
|
||||
return this.with(self -> {
|
||||
self.port = new u16(port);
|
||||
return self;
|
||||
});
|
||||
}
|
||||
|
||||
public Net withConcurrency(short conc) {
|
||||
return this.with(self -> {
|
||||
self.concurrency = new u8(conc);
|
||||
return self;
|
||||
});
|
||||
}
|
||||
|
||||
public Net withMsg(Function<Msg, Msg> f) {
|
||||
return this.with(self -> {
|
||||
self.msg = f.apply(self.msg);
|
||||
return self;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public final class Msg implements Cloneable {
|
||||
|
||||
private Optional<u16> tokenSeed = Optional.empty();
|
||||
private Optional<u16> probingRateBytesPerSecond = Optional.empty();
|
||||
private Optional<Duration> multicastResponseLeisure = Optional.empty();
|
||||
private Con con;
|
||||
private Non non;
|
||||
|
||||
public Msg() {
|
||||
this.con = new Con();
|
||||
this.non = new Non();
|
||||
}
|
||||
|
||||
private Msg with(Function<Msg, Msg> f) {
|
||||
return f.apply(this.clone());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return switch (other) {
|
||||
case Msg o -> o.tokenSeed == this.tokenSeed &&
|
||||
o.probingRateBytesPerSecond == this.probingRateBytesPerSecond &&
|
||||
o.multicastResponseLeisure == this.multicastResponseLeisure &&
|
||||
o.con == this.con &&
|
||||
o.non == this.non;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public Msg clone() {
|
||||
Msg self = new Msg();
|
||||
self.tokenSeed = this.tokenSeed;
|
||||
self.probingRateBytesPerSecond = this.probingRateBytesPerSecond;
|
||||
self.multicastResponseLeisure = this.multicastResponseLeisure;
|
||||
self.con = this.con.clone();
|
||||
self.non = this.non.clone();
|
||||
return self;
|
||||
}
|
||||
|
||||
public Optional<Integer> tokenSeed() {
|
||||
return this.tokenSeed.map(u16 -> u16.intValue());
|
||||
}
|
||||
|
||||
public Optional<Integer> probingRateBytesPerSecond() {
|
||||
return this.probingRateBytesPerSecond.map(u16 -> u16.intValue());
|
||||
}
|
||||
|
||||
public Optional<Duration> multicastResponseLeisure() {
|
||||
return this.multicastResponseLeisure;
|
||||
}
|
||||
|
||||
public Con con() {
|
||||
return this.con;
|
||||
}
|
||||
|
||||
public Non non() {
|
||||
return this.non;
|
||||
}
|
||||
|
||||
public Msg withTokenSeed(int tokenSeed) {
|
||||
return this.with(self -> {
|
||||
self.tokenSeed = Optional.of(new u16(tokenSeed));
|
||||
return self;
|
||||
});
|
||||
}
|
||||
|
||||
public Msg withProbingRateBytesBerSecond(int bps) {
|
||||
return this.with(m -> {
|
||||
m.probingRateBytesPerSecond = Optional.of(new u16(bps));
|
||||
return m;
|
||||
});
|
||||
}
|
||||
|
||||
public Msg withMulticastResponseLeisure(Duration dur) {
|
||||
return this.with(m -> {
|
||||
m.multicastResponseLeisure = Optional.of(dur);
|
||||
return m;
|
||||
});
|
||||
}
|
||||
|
||||
public Msg withCon(Function<Con, Con> f) {
|
||||
return this.with(m -> {
|
||||
m.con = f.apply(m.con);
|
||||
return m;
|
||||
});
|
||||
}
|
||||
|
||||
public Msg withNon(Function<Non, Non> f) {
|
||||
return this.with(m -> {
|
||||
m.non = f.apply(m.non);
|
||||
return m;
|
||||
});
|
||||
}
|
||||
|
||||
public final class Con implements Cloneable {
|
||||
|
||||
private Optional<RetryStrategy> ackedRetryStrategy = Optional.empty();
|
||||
private Optional<RetryStrategy> unackedRetryStrategy = Optional.empty();
|
||||
private Optional<u16> maxAttempts = Optional.empty();
|
||||
|
||||
public Con() {}
|
||||
|
||||
private Con with(Function<Con, Con> f) {
|
||||
return f.apply(this.clone());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return switch (other) {
|
||||
case Con o -> this.ackedRetryStrategy == o.ackedRetryStrategy &&
|
||||
this.unackedRetryStrategy == o.unackedRetryStrategy &&
|
||||
this.maxAttempts == o.maxAttempts;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
public Optional<RetryStrategy> ackedRetryStrategy() {
|
||||
return this.ackedRetryStrategy;
|
||||
}
|
||||
|
||||
public Optional<RetryStrategy> unackedRetryStrategy() {
|
||||
return this.unackedRetryStrategy;
|
||||
}
|
||||
|
||||
public Optional<Integer> maxAttempts() {
|
||||
return this.maxAttempts.map(u16 -> u16.intValue());
|
||||
}
|
||||
|
||||
public Con withAckedRetryStrategy(RetryStrategy r) {
|
||||
return this.with(s -> {
|
||||
s.ackedRetryStrategy = Optional.of(r);
|
||||
return s;
|
||||
});
|
||||
}
|
||||
|
||||
public Con withUnackedRetryStrategy(RetryStrategy r) {
|
||||
return this.with(s -> {
|
||||
s.unackedRetryStrategy = Optional.of(r);
|
||||
return s;
|
||||
});
|
||||
}
|
||||
|
||||
public Con withMaxAttempts(int a) {
|
||||
return this.with(s -> {
|
||||
s.maxAttempts = Optional.of(new u16(a));
|
||||
return s;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Con clone() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
public final class Non implements Cloneable {
|
||||
|
||||
private Optional<RetryStrategy> retryStrategy = Optional.empty();
|
||||
private Optional<u16> maxAttempts = Optional.empty();
|
||||
|
||||
public Non() {}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object other) {
|
||||
return switch (other) {
|
||||
case Non o -> this.retryStrategy == o.retryStrategy &&
|
||||
this.maxAttempts == o.maxAttempts;
|
||||
default -> false;
|
||||
};
|
||||
}
|
||||
|
||||
private Non with(Function<Non, Non> f) {
|
||||
return f.apply(this.clone());
|
||||
}
|
||||
|
||||
public Optional<RetryStrategy> retryStrategy() {
|
||||
return this.retryStrategy;
|
||||
}
|
||||
|
||||
public Optional<Integer> maxAttempts() {
|
||||
return this.maxAttempts.map(u16 -> u16.intValue());
|
||||
}
|
||||
|
||||
public Non withRetryStrategy(RetryStrategy r) {
|
||||
return this.with(s -> {
|
||||
s.retryStrategy = Optional.of(r);
|
||||
return s;
|
||||
});
|
||||
}
|
||||
|
||||
public Non withMaxAttempts(int a) {
|
||||
return this.with(s -> {
|
||||
s.maxAttempts = Optional.of(new u16(a));
|
||||
return s;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Non clone() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user