mirror of
https://gitlab.com/veilid/veilid.git
synced 2025-02-25 18:55:38 -06:00
executor work
This commit is contained in:
parent
ebea72c9db
commit
fdbb4c6397
20
Cargo.lock
generated
20
Cargo.lock
generated
@ -366,7 +366,6 @@ version = "0.8.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a5c45a0dd44b7e6533ac4e7acc38ead1a3b39885f5bbb738140d30ea528abc7c"
|
checksum = "a5c45a0dd44b7e6533ac4e7acc38ead1a3b39885f5bbb738140d30ea528abc7c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-std",
|
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
@ -380,7 +379,6 @@ version = "0.17.2"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb"
|
checksum = "a1b71b31561643aa8e7df3effe284fa83ab1a840e52294c5f4bd7bfd8b2becbb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-std",
|
|
||||||
"async-tls",
|
"async-tls",
|
||||||
"futures-io",
|
"futures-io",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
@ -402,6 +400,7 @@ dependencies = [
|
|||||||
"futures-util",
|
"futures-util",
|
||||||
"pin-project 1.0.10",
|
"pin-project 1.0.10",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
|
"tokio",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2763,6 +2762,7 @@ dependencies = [
|
|||||||
"futures",
|
"futures",
|
||||||
"libc",
|
"libc",
|
||||||
"log",
|
"log",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3040,6 +3040,8 @@ dependencies = [
|
|||||||
"pin-project 1.0.10",
|
"pin-project 1.0.10",
|
||||||
"rand 0.8.5",
|
"rand 0.8.5",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -3759,6 +3761,7 @@ dependencies = [
|
|||||||
"netlink-proto",
|
"netlink-proto",
|
||||||
"nix 0.22.3",
|
"nix 0.22.3",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4531,6 +4534,7 @@ checksum = "36943ee01a6d67977dd3f84a5a1d2efeb4ada3a1ae771cadfaa535d9d9fc6507"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes 1.1.0",
|
"bytes 1.1.0",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
"futures-io",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"log",
|
"log",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
@ -4786,6 +4790,7 @@ dependencies = [
|
|||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tinyvec",
|
"tinyvec",
|
||||||
|
"tokio",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4805,6 +4810,7 @@ dependencies = [
|
|||||||
"resolv-conf",
|
"resolv-conf",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
"trust-dns-proto",
|
"trust-dns-proto",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4983,7 +4989,6 @@ version = "0.1.0"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"async-std",
|
"async-std",
|
||||||
"async-tungstenite 0.8.0",
|
"async-tungstenite 0.8.0",
|
||||||
"async_executors",
|
|
||||||
"bugsalot",
|
"bugsalot",
|
||||||
"capnp",
|
"capnp",
|
||||||
"capnp-rpc",
|
"capnp-rpc",
|
||||||
@ -5004,6 +5009,8 @@ dependencies = [
|
|||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serial_test",
|
"serial_test",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util 0.6.10",
|
||||||
"veilid-core",
|
"veilid-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -5081,10 +5088,14 @@ dependencies = [
|
|||||||
"static_assertions",
|
"static_assertions",
|
||||||
"stop-token",
|
"stop-token",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tokio-util 0.6.10",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-error",
|
"tracing-error",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"tracing-wasm",
|
"tracing-wasm",
|
||||||
|
"trust-dns-resolver",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
"wasm-bindgen-futures",
|
"wasm-bindgen-futures",
|
||||||
"wasm-bindgen-test",
|
"wasm-bindgen-test",
|
||||||
@ -5104,7 +5115,6 @@ name = "veilid-flutter"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"allo-isolate",
|
"allo-isolate",
|
||||||
"async-std",
|
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"ffi-support",
|
"ffi-support",
|
||||||
"futures",
|
"futures",
|
||||||
@ -5117,6 +5127,7 @@ dependencies = [
|
|||||||
"parking_lot 0.12.1",
|
"parking_lot 0.12.1",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-opentelemetry",
|
"tracing-opentelemetry",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
@ -5157,6 +5168,7 @@ dependencies = [
|
|||||||
"serial_test",
|
"serial_test",
|
||||||
"signal-hook",
|
"signal-hook",
|
||||||
"signal-hook-async-std",
|
"signal-hook-async-std",
|
||||||
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-appender",
|
"tracing-appender",
|
||||||
"tracing-journald",
|
"tracing-journald",
|
||||||
|
@ -10,6 +10,11 @@ license = "LGPL-2.0-or-later OR MPL-2.0 OR (MIT AND BSD-3-Clause)"
|
|||||||
name = "veilid-cli"
|
name = "veilid-cli"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = [ "rt-tokio" ]
|
||||||
|
rt-async-std = [ "async-std", "veilid-core/rt-async-std" ]
|
||||||
|
rt-tokio = [ "tokio", "tokio-util", "veilid-core/rt-tokio" ]
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
cursive = { path = "../external/cursive/cursive", default-features = false, features = ["ncurses-backend", "toml", "rt-async-std"]}
|
cursive = { path = "../external/cursive/cursive", default-features = false, features = ["ncurses-backend", "toml", "rt-async-std"]}
|
||||||
|
|
||||||
@ -17,9 +22,10 @@ cursive = { path = "../external/cursive/cursive", default-features = false, feat
|
|||||||
cursive = { path = "../external/cursive/cursive", default-features = false, features = ["crossterm-backend", "toml", "rt-async-std"]}
|
cursive = { path = "../external/cursive/cursive", default-features = false, features = ["crossterm-backend", "toml", "rt-async-std"]}
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-std = { version = "^1.9", features = ["unstable", "attributes"] }
|
async-std = { version = "^1.9", features = ["unstable", "attributes"], optional = true }
|
||||||
async-tungstenite = { version = "^0.8", features = ["async-std-runtime"] }
|
tokio = { version = "^1", features = ["full"], optional = true }
|
||||||
async_executors = { version = "^0", default-features = false, features = [ "async_std" ]}
|
tokio-util = { version = "^0", features = ["compat"], optional = true}
|
||||||
|
async-tungstenite = { version = "^0.8" }
|
||||||
cursive-flexi-logger-view = { path = "../external/cursive-flexi-logger-view" }
|
cursive-flexi-logger-view = { path = "../external/cursive-flexi-logger-view" }
|
||||||
cursive_buffered_backend = { path = "../external/cursive_buffered_backend" }
|
cursive_buffered_backend = { path = "../external/cursive_buffered_backend" }
|
||||||
# cursive-multiplex = "0.4.0"
|
# cursive-multiplex = "0.4.0"
|
||||||
@ -41,7 +47,7 @@ bugsalot = "^0"
|
|||||||
flexi_logger = { version = "^0", features = ["use_chrono_for_offset"] }
|
flexi_logger = { version = "^0", features = ["use_chrono_for_offset"] }
|
||||||
thiserror = "^1"
|
thiserror = "^1"
|
||||||
crossbeam-channel = "^0"
|
crossbeam-channel = "^0"
|
||||||
veilid-core = { path = "../veilid-core" }
|
veilid-core = { path = "../veilid-core", default_features = false}
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
serial_test = "^0"
|
serial_test = "^0"
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
use crate::command_processor::*;
|
use crate::command_processor::*;
|
||||||
|
use crate::tools::*;
|
||||||
use crate::veilid_client_capnp::*;
|
use crate::veilid_client_capnp::*;
|
||||||
use async_executors::{AsyncStd, LocalSpawnHandleExt};
|
|
||||||
use capnp::capability::Promise;
|
use capnp::capability::Promise;
|
||||||
use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, Disconnector, RpcSystem};
|
use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, Disconnector, RpcSystem};
|
||||||
use futures::io::AsyncReadExt;
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
use std::rc::Rc;
|
use std::rc::Rc;
|
||||||
@ -140,9 +139,7 @@ impl ClientApiConnection {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
let rpc_jh = AsyncStd
|
let rpc_jh = spawn_local(rpc_system);
|
||||||
.spawn_handle_local(rpc_system)
|
|
||||||
.map_err(|e| format!("failed to spawn rpc system: {}", e))?;
|
|
||||||
|
|
||||||
// Send the request and get the state object and the registration object
|
// Send the request and get the state object and the registration object
|
||||||
let response = request
|
let response = request
|
||||||
@ -173,23 +170,43 @@ impl ClientApiConnection {
|
|||||||
// object mapping from the server which we need for the update backchannel
|
// object mapping from the server which we need for the update backchannel
|
||||||
|
|
||||||
// Wait until rpc system completion or disconnect was requested
|
// Wait until rpc system completion or disconnect was requested
|
||||||
rpc_jh
|
|
||||||
.await
|
cfg_if! {
|
||||||
.map_err(|e| format!("client RPC system error: {}", e))
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
rpc_jh
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("client RPC system error: {}", e))
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
rpc_jh
|
||||||
|
.await
|
||||||
|
.map_err(|e| format!("join error: {}", e))?
|
||||||
|
.map_err(|e| format!("client RPC system error: {}", e))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn handle_connection(&mut self) -> Result<(), String> {
|
async fn handle_connection(&mut self) -> Result<(), String> {
|
||||||
trace!("ClientApiConnection::handle_connection");
|
trace!("ClientApiConnection::handle_connection");
|
||||||
let connect_addr = self.inner.borrow().connect_addr.unwrap();
|
let connect_addr = self.inner.borrow().connect_addr.unwrap();
|
||||||
// Connect the TCP socket
|
// Connect the TCP socket
|
||||||
let stream = async_std::net::TcpStream::connect(connect_addr)
|
let stream = TcpStream::connect(connect_addr)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)?;
|
.map_err(map_to_string)?;
|
||||||
// If it succeed, disable nagle algorithm
|
// If it succeed, disable nagle algorithm
|
||||||
stream.set_nodelay(true).map_err(map_to_string)?;
|
stream.set_nodelay(true).map_err(map_to_string)?;
|
||||||
|
|
||||||
// Create the VAT network
|
// Create the VAT network
|
||||||
let (reader, writer) = stream.split();
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
let (reader, writer) = stream.split();
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
let (reader, writer) = stream.into_split();
|
||||||
|
let reader = reader.compat();
|
||||||
|
let writer = writer.compat_write();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let rpc_network = Box::new(twoparty::VatNetwork::new(
|
let rpc_network = Box::new(twoparty::VatNetwork::new(
|
||||||
reader,
|
reader,
|
||||||
writer,
|
writer,
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
use crate::client_api_connection::*;
|
use crate::client_api_connection::*;
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
|
use crate::tools::*;
|
||||||
use crate::ui::*;
|
use crate::ui::*;
|
||||||
use async_std::prelude::FutureExt;
|
|
||||||
use log::*;
|
use log::*;
|
||||||
use std::cell::*;
|
use std::cell::*;
|
||||||
use std::net::SocketAddr;
|
use std::net::SocketAddr;
|
||||||
@ -116,7 +116,7 @@ debug - send a debugging command to the Veilid server
|
|||||||
trace!("CommandProcessor::cmd_shutdown");
|
trace!("CommandProcessor::cmd_shutdown");
|
||||||
let mut capi = self.capi();
|
let mut capi = self.capi();
|
||||||
let ui = self.ui();
|
let ui = self.ui();
|
||||||
async_std::task::spawn_local(async move {
|
spawn_detached_local(async move {
|
||||||
if let Err(e) = capi.server_shutdown().await {
|
if let Err(e) = capi.server_shutdown().await {
|
||||||
error!("Server command 'shutdown' failed to execute: {}", e);
|
error!("Server command 'shutdown' failed to execute: {}", e);
|
||||||
}
|
}
|
||||||
@ -129,7 +129,7 @@ debug - send a debugging command to the Veilid server
|
|||||||
trace!("CommandProcessor::cmd_attach");
|
trace!("CommandProcessor::cmd_attach");
|
||||||
let mut capi = self.capi();
|
let mut capi = self.capi();
|
||||||
let ui = self.ui();
|
let ui = self.ui();
|
||||||
async_std::task::spawn_local(async move {
|
spawn_detached_local(async move {
|
||||||
if let Err(e) = capi.server_attach().await {
|
if let Err(e) = capi.server_attach().await {
|
||||||
error!("Server command 'attach' failed to execute: {}", e);
|
error!("Server command 'attach' failed to execute: {}", e);
|
||||||
}
|
}
|
||||||
@ -142,7 +142,7 @@ debug - send a debugging command to the Veilid server
|
|||||||
trace!("CommandProcessor::cmd_detach");
|
trace!("CommandProcessor::cmd_detach");
|
||||||
let mut capi = self.capi();
|
let mut capi = self.capi();
|
||||||
let ui = self.ui();
|
let ui = self.ui();
|
||||||
async_std::task::spawn_local(async move {
|
spawn_detached_local(async move {
|
||||||
if let Err(e) = capi.server_detach().await {
|
if let Err(e) = capi.server_detach().await {
|
||||||
error!("Server command 'detach' failed to execute: {}", e);
|
error!("Server command 'detach' failed to execute: {}", e);
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ debug - send a debugging command to the Veilid server
|
|||||||
trace!("CommandProcessor::cmd_disconnect");
|
trace!("CommandProcessor::cmd_disconnect");
|
||||||
let mut capi = self.capi();
|
let mut capi = self.capi();
|
||||||
let ui = self.ui();
|
let ui = self.ui();
|
||||||
async_std::task::spawn_local(async move {
|
spawn_detached_local(async move {
|
||||||
capi.disconnect().await;
|
capi.disconnect().await;
|
||||||
ui.send_callback(callback);
|
ui.send_callback(callback);
|
||||||
});
|
});
|
||||||
@ -166,7 +166,7 @@ debug - send a debugging command to the Veilid server
|
|||||||
trace!("CommandProcessor::cmd_debug");
|
trace!("CommandProcessor::cmd_debug");
|
||||||
let mut capi = self.capi();
|
let mut capi = self.capi();
|
||||||
let ui = self.ui();
|
let ui = self.ui();
|
||||||
async_std::task::spawn_local(async move {
|
spawn_detached_local(async move {
|
||||||
match capi.server_debug(rest.unwrap_or_default()).await {
|
match capi.server_debug(rest.unwrap_or_default()).await {
|
||||||
Ok(output) => ui.display_string_dialog("Debug Output", output, callback),
|
Ok(output) => ui.display_string_dialog("Debug Output", output, callback),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -248,9 +248,7 @@ debug - send a debugging command to the Veilid server
|
|||||||
debug!("Connection lost, retrying in 2 seconds");
|
debug!("Connection lost, retrying in 2 seconds");
|
||||||
{
|
{
|
||||||
let waker = self.inner_mut().connection_waker.instance_clone(());
|
let waker = self.inner_mut().connection_waker.instance_clone(());
|
||||||
waker
|
let _ = timeout(Duration::from_millis(2000), waker).await;
|
||||||
.race(async_std::task::sleep(Duration::from_millis(2000)))
|
|
||||||
.await;
|
|
||||||
}
|
}
|
||||||
self.inner_mut().connection_waker.reset();
|
self.inner_mut().connection_waker.reset();
|
||||||
first = false;
|
first = false;
|
||||||
@ -306,7 +304,7 @@ debug - send a debugging command to the Veilid server
|
|||||||
// pub fn stop_connection(&mut self) {
|
// pub fn stop_connection(&mut self) {
|
||||||
// self.inner_mut().reconnect = false;
|
// self.inner_mut().reconnect = false;
|
||||||
// let mut capi = self.capi().clone();
|
// let mut capi = self.capi().clone();
|
||||||
// async_std::task::spawn_local(async move {
|
// spawn_detached(async move {
|
||||||
// capi.disconnect().await;
|
// capi.disconnect().await;
|
||||||
// });
|
// });
|
||||||
// }
|
// }
|
||||||
@ -327,7 +325,7 @@ debug - send a debugging command to the Veilid server
|
|||||||
trace!("CommandProcessor::attach");
|
trace!("CommandProcessor::attach");
|
||||||
let mut capi = self.capi();
|
let mut capi = self.capi();
|
||||||
|
|
||||||
async_std::task::spawn_local(async move {
|
spawn_detached_local(async move {
|
||||||
if let Err(e) = capi.server_attach().await {
|
if let Err(e) = capi.server_attach().await {
|
||||||
error!("Server command 'attach' failed to execute: {}", e);
|
error!("Server command 'attach' failed to execute: {}", e);
|
||||||
}
|
}
|
||||||
@ -338,7 +336,7 @@ debug - send a debugging command to the Veilid server
|
|||||||
trace!("CommandProcessor::detach");
|
trace!("CommandProcessor::detach");
|
||||||
let mut capi = self.capi();
|
let mut capi = self.capi();
|
||||||
|
|
||||||
async_std::task::spawn_local(async move {
|
spawn_detached_local(async move {
|
||||||
if let Err(e) = capi.server_detach().await {
|
if let Err(e) = capi.server_detach().await {
|
||||||
error!("Server command 'detach' failed to execute: {}", e);
|
error!("Server command 'detach' failed to execute: {}", e);
|
||||||
}
|
}
|
||||||
|
@ -3,16 +3,17 @@
|
|||||||
|
|
||||||
use veilid_core::xx::*;
|
use veilid_core::xx::*;
|
||||||
|
|
||||||
use async_std::prelude::*;
|
|
||||||
use clap::{Arg, ColorChoice, Command};
|
use clap::{Arg, ColorChoice, Command};
|
||||||
use flexi_logger::*;
|
use flexi_logger::*;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::net::ToSocketAddrs;
|
use std::net::ToSocketAddrs;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use tools::*;
|
||||||
|
|
||||||
mod client_api_connection;
|
mod client_api_connection;
|
||||||
mod command_processor;
|
mod command_processor;
|
||||||
mod settings;
|
mod settings;
|
||||||
|
mod tools;
|
||||||
mod ui;
|
mod ui;
|
||||||
|
|
||||||
#[allow(clippy::all)]
|
#[allow(clippy::all)]
|
||||||
@ -60,8 +61,7 @@ fn parse_command_line(default_config_path: &OsStr) -> Result<clap::ArgMatches, S
|
|||||||
Ok(matches)
|
Ok(matches)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_std::main]
|
fn main() -> Result<(), String> {
|
||||||
async fn main() -> Result<(), String> {
|
|
||||||
// Get command line options
|
// Get command line options
|
||||||
let default_config_path = settings::Settings::get_default_config_path();
|
let default_config_path = settings::Settings::get_default_config_path();
|
||||||
let matches = parse_command_line(default_config_path.as_os_str())?;
|
let matches = parse_command_line(default_config_path.as_os_str())?;
|
||||||
@ -170,17 +170,29 @@ async fn main() -> Result<(), String> {
|
|||||||
comproc.set_server_address(server_addr);
|
comproc.set_server_address(server_addr);
|
||||||
let mut comproc2 = comproc.clone();
|
let mut comproc2 = comproc.clone();
|
||||||
let connection_future = comproc.connection_manager();
|
let connection_future = comproc.connection_manager();
|
||||||
// Start UI
|
|
||||||
let ui_future = async_std::task::spawn_local(async move {
|
|
||||||
sivui.run_async().await;
|
|
||||||
|
|
||||||
// When UI quits, close connection and command processor cleanly
|
// Start async
|
||||||
comproc2.quit();
|
block_on(async move {
|
||||||
capi.disconnect().await;
|
// Start UI
|
||||||
|
let ui_future = async move {
|
||||||
|
sivui.run_async().await;
|
||||||
|
|
||||||
|
// When UI quits, close connection and command processor cleanly
|
||||||
|
comproc2.quit();
|
||||||
|
capi.disconnect().await;
|
||||||
|
};
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
use async_std::prelude::*;
|
||||||
|
// Wait for ui and connection to complete
|
||||||
|
let _ = ui_future.join(connection_future).await;
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
// Wait for ui and connection to complete
|
||||||
|
let _ = tokio::join!(ui_future, connection_future);
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Wait for ui and connection to complete
|
|
||||||
ui_future.join(connection_future).await;
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
40
veilid-cli/src/tools.rs
Normal file
40
veilid-cli/src/tools.rs
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
use cfg_if::*;
|
||||||
|
use core::future::Future;
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
pub use async_std::task::JoinHandle;
|
||||||
|
pub use async_std::net::TcpStream;
|
||||||
|
pub use async_std::future::TimeoutError;
|
||||||
|
pub fn spawn_local<F: Future<Output = T> + 'static, T: 'static>(f: F) -> JoinHandle<T> {
|
||||||
|
async_std::task::spawn_local(f)
|
||||||
|
}
|
||||||
|
pub fn spawn_detached_local<F: Future<Output = T> + 'static, T: 'static>(f: F) {
|
||||||
|
let _ = async_std::task::spawn_local(f);
|
||||||
|
}
|
||||||
|
pub use async_std::task::sleep;
|
||||||
|
pub use async_std::future::timeout;
|
||||||
|
pub fn block_on<F: Future<Output = T>, T>(f: F) -> T {
|
||||||
|
async_std::task::block_on(f)
|
||||||
|
}
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
pub use tokio::task::JoinHandle;
|
||||||
|
pub use tokio::net::TcpStream;
|
||||||
|
pub use tokio_util::compat::*;
|
||||||
|
pub use tokio::time::error::Elapsed as TimeoutError;
|
||||||
|
pub fn spawn_local<F: Future<Output = T> + 'static, T: 'static>(f: F) -> JoinHandle<T> {
|
||||||
|
tokio::task::spawn_local(f)
|
||||||
|
}
|
||||||
|
pub fn spawn_detached_local<F: Future<Output = T> + 'static, T: 'static>(f: F) {
|
||||||
|
let _ = tokio::task::spawn_local(f);
|
||||||
|
}
|
||||||
|
pub use tokio::time::sleep;
|
||||||
|
pub use tokio::time::timeout;
|
||||||
|
pub fn block_on<F: Future<Output = T>, T>(f: F) -> T {
|
||||||
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
let local = tokio::task::LocalSet::new();
|
||||||
|
local.block_on(&rt, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -10,11 +10,13 @@ license = "LGPL-2.0-or-later OR MPL-2.0 OR (MIT AND BSD-3-Clause)"
|
|||||||
crate-type = ["cdylib", "staticlib", "rlib"]
|
crate-type = ["cdylib", "staticlib", "rlib"]
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "rt-async-std" ]
|
default = []
|
||||||
|
rt-async-std = [ "async-std", "async-std-resolver", "async_executors/async_std", "rtnetlink?/smol_socket" ]
|
||||||
|
rt-tokio = [ "tokio", "tokio-util", "tokio-stream", "trust-dns-resolver/tokio-runtime", "async_executors/tokio_tp", "async_executors/tokio_io", "async_executors/tokio_timer", "rtnetlink?/tokio_socket" ]
|
||||||
|
|
||||||
android_tests = []
|
android_tests = []
|
||||||
ios_tests = [ "simplelog", "backtrace" ]
|
ios_tests = [ "simplelog", "backtrace" ]
|
||||||
tracking = [ "backtrace" ]
|
tracking = [ "backtrace" ]
|
||||||
rt-async-std = [ "async-std", "async-tungstenite/async-std-runtime", "async-std-resolver", "async_executors/async_std", "rtnetlink?/smol_socket" ]
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tracing = { version = "^0", features = ["log", "attributes"] }
|
tracing = { version = "^0", features = ["log", "attributes"] }
|
||||||
@ -59,9 +61,13 @@ rtnetlink = { version = "^0", default-features = false, optional = true }
|
|||||||
# Linux, Windows, Mac, iOS, Android
|
# Linux, Windows, Mac, iOS, Android
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
async-std = { version = "^1", features = ["unstable"], optional = true}
|
async-std = { version = "^1", features = ["unstable"], optional = true}
|
||||||
|
tokio = { version = "^1", features = ["full"], optional = true}
|
||||||
|
tokio-util = { version = "^0", features = ["compat"], optional = true}
|
||||||
|
tokio-stream = { version = "^0", features = ["net"], optional = true}
|
||||||
async-io = { version = "^1" }
|
async-io = { version = "^1" }
|
||||||
async-tungstenite = { version = "^0", features = ["async-tls"] }
|
async-tungstenite = { version = "^0", features = ["async-tls"] }
|
||||||
async-std-resolver = { version = "^0", optional = true }
|
async-std-resolver = { version = "^0", optional = true }
|
||||||
|
trust-dns-resolver = { version = "^0", optional = true }
|
||||||
maplit = "^1"
|
maplit = "^1"
|
||||||
config = { version = "^0", features = ["yaml"] }
|
config = { version = "^0", features = ["yaml"] }
|
||||||
keyring-manager = { path = "../external/keyring-manager" }
|
keyring-manager = { path = "../external/keyring-manager" }
|
||||||
@ -77,7 +83,6 @@ data-encoding = { version = "^2" }
|
|||||||
serde = { version = "^1", features = ["derive" ] }
|
serde = { version = "^1", features = ["derive" ] }
|
||||||
serde_cbor = { version = "^0" }
|
serde_cbor = { version = "^0" }
|
||||||
serde_json = { version = "^1" }
|
serde_json = { version = "^1" }
|
||||||
async_executors = { version = "^0", default-features = false }
|
|
||||||
socket2 = "^0"
|
socket2 = "^0"
|
||||||
bugsalot = "^0"
|
bugsalot = "^0"
|
||||||
chrono = "^0"
|
chrono = "^0"
|
||||||
|
@ -97,24 +97,6 @@ impl ApiTracingLayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn display_current_thread_id() -> String {
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(target_arch = "wasm32")] {
|
|
||||||
"".to_owned()
|
|
||||||
} else {
|
|
||||||
format!("({}:{:?})",
|
|
||||||
if let Some(n) = async_std::task::current().name() {
|
|
||||||
n.to_string()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
async_std::task::current().id().to_string()
|
|
||||||
},
|
|
||||||
std::thread::current().id()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<S: Subscriber + for<'a> registry::LookupSpan<'a>> Layer<S> for ApiTracingLayer {
|
impl<S: Subscriber + for<'a> registry::LookupSpan<'a>> Layer<S> for ApiTracingLayer {
|
||||||
fn enabled(&self, metadata: &tracing::Metadata<'_>, _: layer::Context<'_, S>) -> bool {
|
fn enabled(&self, metadata: &tracing::Metadata<'_>, _: layer::Context<'_, S>) -> bool {
|
||||||
if let Some(inner) = &mut *self.inner.lock() {
|
if let Some(inner) = &mut *self.inner.lock() {
|
||||||
@ -188,7 +170,7 @@ impl<S: Subscriber + for<'a> registry::LookupSpan<'a>> Layer<S> for ApiTracingLa
|
|||||||
.and_then(|file| meta.line().map(|ln| format!("{}:{}", file, ln)))
|
.and_then(|file| meta.line().map(|ln| format!("{}:{}", file, ln)))
|
||||||
.unwrap_or_default();
|
.unwrap_or_default();
|
||||||
|
|
||||||
let message = format!("{}{} {}", origin, display_current_thread_id(), recorder);
|
let message = format!("{} {}", origin, recorder);
|
||||||
|
|
||||||
(inner.update_callback)(VeilidUpdate::Log(VeilidStateLog {
|
(inner.update_callback)(VeilidUpdate::Log(VeilidStateLog {
|
||||||
log_level,
|
log_level,
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use crate::callback_state_machine::*;
|
use crate::callback_state_machine::*;
|
||||||
use crate::dht::Crypto;
|
use crate::dht::Crypto;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::network_manager::*;
|
use crate::network_manager::*;
|
||||||
use crate::routing_table::*;
|
use crate::routing_table::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
@ -306,9 +305,8 @@ impl AttachmentManager {
|
|||||||
// Create long-running connection maintenance routine
|
// Create long-running connection maintenance routine
|
||||||
let this = self.clone();
|
let this = self.clone();
|
||||||
self.inner.lock().maintain_peers = true;
|
self.inner.lock().maintain_peers = true;
|
||||||
self.inner.lock().attachment_maintainer_jh = Some(MustJoinHandle::new(intf::spawn(
|
self.inner.lock().attachment_maintainer_jh =
|
||||||
this.attachment_maintainer(),
|
Some(intf::spawn(this.attachment_maintainer()));
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", skip(self))]
|
#[instrument(level = "trace", skip(self))]
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use crate::api_tracing_layer::*;
|
use crate::api_tracing_layer::*;
|
||||||
use crate::attachment_manager::*;
|
use crate::attachment_manager::*;
|
||||||
use crate::dht::Crypto;
|
use crate::dht::Crypto;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::veilid_api::*;
|
use crate::veilid_api::*;
|
||||||
use crate::veilid_config::*;
|
use crate::veilid_config::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
@ -10,7 +9,6 @@ cfg_if! {
|
|||||||
if #[cfg(target_arch = "wasm32")] {
|
if #[cfg(target_arch = "wasm32")] {
|
||||||
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate)>;
|
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate)>;
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate) + Send + Sync>;
|
pub type UpdateCallback = Arc<dyn Fn(VeilidUpdate) + Send + Sync>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -255,7 +253,9 @@ impl VeilidCoreContext {
|
|||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
static INITIALIZED: AsyncMutex<bool> = AsyncMutex::new(false);
|
lazy_static::lazy_static! {
|
||||||
|
static ref INITIALIZED: AsyncMutex<bool> = AsyncMutex::new(false);
|
||||||
|
}
|
||||||
|
|
||||||
#[instrument(err, skip_all)]
|
#[instrument(err, skip_all)]
|
||||||
pub async fn api_startup(
|
pub async fn api_startup(
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use super::key::*;
|
use super::key::*;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use chacha20::cipher::{KeyIvInit, StreamCipher};
|
use chacha20::cipher::{KeyIvInit, StreamCipher};
|
||||||
@ -124,7 +123,7 @@ impl Crypto {
|
|||||||
|
|
||||||
// Schedule flushing
|
// Schedule flushing
|
||||||
let this = self.clone();
|
let this = self.clone();
|
||||||
let flush_future = interval(60000, move || {
|
let flush_future = intf::interval(60000, move || {
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
async move {
|
async move {
|
||||||
if let Err(e) = this.flush().await {
|
if let Err(e) = this.flush().await {
|
||||||
@ -214,13 +213,13 @@ impl Crypto {
|
|||||||
|
|
||||||
pub fn get_random_nonce() -> Nonce {
|
pub fn get_random_nonce() -> Nonce {
|
||||||
let mut nonce = [0u8; 24];
|
let mut nonce = [0u8; 24];
|
||||||
random_bytes(&mut nonce).unwrap();
|
intf::random_bytes(&mut nonce).unwrap();
|
||||||
nonce
|
nonce
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_random_secret() -> SharedSecret {
|
pub fn get_random_secret() -> SharedSecret {
|
||||||
let mut s = [0u8; 32];
|
let mut s = [0u8; 32];
|
||||||
random_bytes(&mut s).unwrap();
|
intf::random_bytes(&mut s).unwrap();
|
||||||
s
|
s
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
mod table_db;
|
mod table_db;
|
||||||
use crate::xx::*;
|
|
||||||
|
|
||||||
#[cfg(target_arch = "wasm32")]
|
#[cfg(target_arch = "wasm32")]
|
||||||
mod wasm;
|
mod wasm;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::intf::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
struct BlockStoreInner {
|
struct BlockStoreInner {
|
||||||
|
@ -1,14 +1,33 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
pub use async_executors::JoinHandle;
|
cfg_if! {
|
||||||
use async_executors::{AsyncStd, LocalSpawnHandleExt, SpawnHandleExt};
|
if #[cfg(feature="rt-async-std")] {
|
||||||
use async_std_resolver::{config, resolver, resolver_from_system_conf, AsyncStdResolver};
|
use async_std_resolver::{config, resolver, resolver_from_system_conf, AsyncStdResolver as AsyncResolver};
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
use trust_dns_resolver::{config, TokioAsyncResolver as AsyncResolver, error::ResolveError};
|
||||||
|
|
||||||
|
pub async fn resolver(
|
||||||
|
config: config::ResolverConfig,
|
||||||
|
options: config::ResolverOpts,
|
||||||
|
) -> Result<AsyncResolver, ResolveError> {
|
||||||
|
AsyncResolver::tokio(config, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Constructs a new async-std based Resolver with the system configuration.
|
||||||
|
///
|
||||||
|
/// This will use `/etc/resolv.conf` on Unix OSes and the registry on Windows.
|
||||||
|
#[cfg(any(unix, target_os = "windows"))]
|
||||||
|
pub async fn resolver_from_system_conf() -> Result<AsyncResolver, ResolveError> {
|
||||||
|
AsyncResolver::tokio_from_system_conf()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
||||||
|
|
||||||
lazy_static::lazy_static! {
|
lazy_static::lazy_static! {
|
||||||
static ref RESOLVER: Arc<AsyncMutex<Option<AsyncStdResolver>>> = Arc::new(AsyncMutex::new(None));
|
static ref RESOLVER: Arc<AsyncMutex<Option<AsyncResolver>>> = Arc::new(AsyncMutex::new(None));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_timestamp() -> u64 {
|
pub fn get_timestamp() -> u64 {
|
||||||
@ -40,9 +59,21 @@ pub fn get_random_u64() -> u64 {
|
|||||||
|
|
||||||
pub async fn sleep(millis: u32) {
|
pub async fn sleep(millis: u32) {
|
||||||
if millis == 0 {
|
if millis == 0 {
|
||||||
async_std::task::yield_now().await;
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
async_std::task::yield_now().await;
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
tokio::task::yield_now().await;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
async_std::task::sleep(Duration::from_millis(u64::from(millis))).await;
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
async_std::task::sleep(Duration::from_millis(u64::from(millis))).await;
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
tokio::time::sleep(Duration::from_millis(u64::from(millis))).await;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,22 +83,64 @@ pub fn system_boxed<'a, Out>(
|
|||||||
Box::pin(future)
|
Box::pin(future)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn<Out>(future: impl Future<Output = Out> + Send + 'static) -> JoinHandle<Out>
|
pub fn spawn<Out>(future: impl Future<Output = Out> + Send + 'static) -> MustJoinHandle<Out>
|
||||||
where
|
where
|
||||||
Out: Send + 'static,
|
Out: Send + 'static,
|
||||||
{
|
{
|
||||||
AsyncStd
|
cfg_if! {
|
||||||
.spawn_handle(future)
|
if #[cfg(feature="rt-async-std")] {
|
||||||
.expect("async-std spawn should never error out")
|
MustJoinHandle::new(async_std::task::spawn(future))
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
MustJoinHandle::new(tokio::task::spawn(future))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_local<Out>(future: impl Future<Output = Out> + 'static) -> JoinHandle<Out>
|
pub fn spawn_local<Out>(future: impl Future<Output = Out> + 'static) -> MustJoinHandle<Out>
|
||||||
where
|
where
|
||||||
Out: 'static,
|
Out: 'static,
|
||||||
{
|
{
|
||||||
AsyncStd
|
cfg_if! {
|
||||||
.spawn_handle_local(future)
|
if #[cfg(feature="rt-async-std")] {
|
||||||
.expect("async-std spawn_local should never error out")
|
MustJoinHandle::new(async_std::task::spawn_local(future))
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
MustJoinHandle::new(tokio::task::spawn_local(future))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_with_local_set<Out>(
|
||||||
|
future: impl Future<Output = Out> + Send + 'static,
|
||||||
|
) -> MustJoinHandle<Out>
|
||||||
|
where
|
||||||
|
Out: Send + 'static,
|
||||||
|
{
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
spawn(future)
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
MustJoinHandle::new(tokio::task::spawn_blocking(move || {
|
||||||
|
let rt = tokio::runtime::Handle::current();
|
||||||
|
rt.block_on(async {
|
||||||
|
let local = tokio::task::LocalSet::new();
|
||||||
|
local.run_until(future).await
|
||||||
|
})
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_detached<Out>(future: impl Future<Output = Out> + Send + 'static)
|
||||||
|
where
|
||||||
|
Out: Send + 'static,
|
||||||
|
{
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
drop(async_std::task::spawn(future));
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
drop(tokio::task::spawn(future));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn interval<F, FUT>(freq_ms: u32, callback: F) -> SystemPinBoxFuture<()>
|
pub fn interval<F, FUT>(freq_ms: u32, callback: F) -> SystemPinBoxFuture<()>
|
||||||
@ -90,13 +163,25 @@ where
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub use async_std::future::TimeoutError;
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
pub use async_std::future::TimeoutError;
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
pub use tokio::time::error::Elapsed as TimeoutError;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn timeout<F, T>(dur_ms: u32, f: F) -> Result<T, TimeoutError>
|
pub async fn timeout<F, T>(dur_ms: u32, f: F) -> Result<T, TimeoutError>
|
||||||
where
|
where
|
||||||
F: Future<Output = T>,
|
F: Future<Output = T>,
|
||||||
{
|
{
|
||||||
async_std::future::timeout(Duration::from_millis(dur_ms as u64), f).await
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
async_std::future::timeout(Duration::from_millis(dur_ms as u64), f).await
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
tokio::time::timeout(Duration::from_millis(dur_ms as u64), f).await
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_concurrency() -> u32 {
|
pub fn get_concurrency() -> u32 {
|
||||||
@ -128,7 +213,7 @@ where
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
async fn get_resolver() -> Result<AsyncStdResolver, String> {
|
async fn get_resolver() -> Result<AsyncResolver, String> {
|
||||||
let mut resolver_lock = RESOLVER.lock().await;
|
let mut resolver_lock = RESOLVER.lock().await;
|
||||||
if let Some(r) = &*resolver_lock {
|
if let Some(r) = &*resolver_lock {
|
||||||
Ok(r.clone())
|
Ok(r.clone())
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::intf::table_db::*;
|
use crate::intf::table_db::*;
|
||||||
use crate::intf::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use keyvaluedb_sqlite::*;
|
use keyvaluedb_sqlite::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
@ -11,7 +11,13 @@ use rtnetlink::packet::{
|
|||||||
nlas::address::Nla, AddressMessage, AF_INET, AF_INET6, IFA_F_DADFAILED, IFA_F_DEPRECATED,
|
nlas::address::Nla, AddressMessage, AF_INET, AF_INET6, IFA_F_DADFAILED, IFA_F_DEPRECATED,
|
||||||
IFA_F_OPTIMISTIC, IFA_F_PERMANENT, IFA_F_TEMPORARY, IFA_F_TENTATIVE,
|
IFA_F_OPTIMISTIC, IFA_F_PERMANENT, IFA_F_TEMPORARY, IFA_F_TENTATIVE,
|
||||||
};
|
};
|
||||||
use rtnetlink::{new_connection_with_socket, sys::SmolSocket, Handle, IpVersion};
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
use rtnetlink::{new_connection_with_socket, sys::SmolSocket as RTNetLinkSocket, Handle, IpVersion};
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
use rtnetlink::{new_connection_with_socket, sys::TokioSocket as RTNetLinkSocket, Handle, IpVersion};
|
||||||
|
}
|
||||||
|
}
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::io;
|
use std::io;
|
||||||
@ -54,24 +60,16 @@ fn flags_to_address_flags(flags: u32) -> AddressFlags {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct PlatformSupportNetlink {
|
pub struct PlatformSupportNetlink {
|
||||||
_connection_jh: intf::JoinHandle<()>,
|
connection_jh: Option<MustJoinHandle<()>>,
|
||||||
handle: Handle,
|
handle: Option<Handle>,
|
||||||
default_route_interfaces: BTreeSet<u32>,
|
default_route_interfaces: BTreeSet<u32>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PlatformSupportNetlink {
|
impl PlatformSupportNetlink {
|
||||||
pub fn new() -> Result<Self, String> {
|
pub fn new() -> Result<Self, String> {
|
||||||
// Get the netlink connection
|
|
||||||
let (connection, handle, _) = new_connection_with_socket::<SmolSocket>()
|
|
||||||
.map_err(map_to_string)
|
|
||||||
.map_err(logthru_net!(error))?;
|
|
||||||
|
|
||||||
// Spawn a connection handler
|
|
||||||
let _connection_jh = intf::spawn(connection);
|
|
||||||
|
|
||||||
Ok(PlatformSupportNetlink {
|
Ok(PlatformSupportNetlink {
|
||||||
_connection_jh,
|
connection_jh: None,
|
||||||
handle,
|
handle: None,
|
||||||
default_route_interfaces: BTreeSet::new(),
|
default_route_interfaces: BTreeSet::new(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -79,7 +77,13 @@ impl PlatformSupportNetlink {
|
|||||||
// Figure out which interfaces have default routes
|
// Figure out which interfaces have default routes
|
||||||
async fn refresh_default_route_interfaces(&mut self) -> Result<(), String> {
|
async fn refresh_default_route_interfaces(&mut self) -> Result<(), String> {
|
||||||
self.default_route_interfaces.clear();
|
self.default_route_interfaces.clear();
|
||||||
let mut routesv4 = self.handle.route().get(IpVersion::V4).execute();
|
let mut routesv4 = self
|
||||||
|
.handle
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.route()
|
||||||
|
.get(IpVersion::V4)
|
||||||
|
.execute();
|
||||||
while let Some(routev4) = routesv4.try_next().await.unwrap_or_default() {
|
while let Some(routev4) = routesv4.try_next().await.unwrap_or_default() {
|
||||||
if let Some(index) = routev4.output_interface() {
|
if let Some(index) = routev4.output_interface() {
|
||||||
//println!("*** ipv4 route: {:#?}", routev4);
|
//println!("*** ipv4 route: {:#?}", routev4);
|
||||||
@ -88,7 +92,13 @@ impl PlatformSupportNetlink {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let mut routesv6 = self.handle.route().get(IpVersion::V6).execute();
|
let mut routesv6 = self
|
||||||
|
.handle
|
||||||
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.route()
|
||||||
|
.get(IpVersion::V6)
|
||||||
|
.execute();
|
||||||
while let Some(routev6) = routesv6.try_next().await.unwrap_or_default() {
|
while let Some(routev6) = routesv6.try_next().await.unwrap_or_default() {
|
||||||
if let Some(index) = routev6.output_interface() {
|
if let Some(index) = routev6.output_interface() {
|
||||||
//println!("*** ipv6 route: {:#?}", routev6);
|
//println!("*** ipv6 route: {:#?}", routev6);
|
||||||
@ -228,7 +238,7 @@ impl PlatformSupportNetlink {
|
|||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_interfaces(
|
async fn get_interfaces_internal(
|
||||||
&mut self,
|
&mut self,
|
||||||
interfaces: &mut BTreeMap<String, NetworkInterface>,
|
interfaces: &mut BTreeMap<String, NetworkInterface>,
|
||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
@ -242,7 +252,7 @@ impl PlatformSupportNetlink {
|
|||||||
|
|
||||||
// Ask for all the addresses we have
|
// Ask for all the addresses we have
|
||||||
let mut names = BTreeMap::<u32, String>::new();
|
let mut names = BTreeMap::<u32, String>::new();
|
||||||
let mut addresses = self.handle.address().get().execute();
|
let mut addresses = self.handle.as_ref().unwrap().address().get().execute();
|
||||||
while let Some(msg) = addresses
|
while let Some(msg) = addresses
|
||||||
.try_next()
|
.try_next()
|
||||||
.await
|
.await
|
||||||
@ -302,4 +312,30 @@ impl PlatformSupportNetlink {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn get_interfaces(
|
||||||
|
&mut self,
|
||||||
|
interfaces: &mut BTreeMap<String, NetworkInterface>,
|
||||||
|
) -> Result<(), String> {
|
||||||
|
// Get the netlink connection
|
||||||
|
let (connection, handle, _) = new_connection_with_socket::<RTNetLinkSocket>()
|
||||||
|
.map_err(map_to_string)
|
||||||
|
.map_err(logthru_net!(error))?;
|
||||||
|
|
||||||
|
// Spawn a connection handler
|
||||||
|
let connection_jh = intf::spawn(connection);
|
||||||
|
|
||||||
|
// Save the connection
|
||||||
|
self.connection_jh = Some(connection_jh);
|
||||||
|
self.handle = Some(handle);
|
||||||
|
|
||||||
|
// Do the work
|
||||||
|
let out = self.get_interfaces_internal(interfaces).await;
|
||||||
|
|
||||||
|
// Clean up connection
|
||||||
|
drop(self.handle.take());
|
||||||
|
self.connection_jh.take().unwrap().abort().await;
|
||||||
|
|
||||||
|
out
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::intf::*;
|
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
|
use crate::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
use crate::intf::*;
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
struct BlockStoreInner {
|
struct BlockStoreInner {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use super::utils;
|
use super::utils;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
pub use async_executors::JoinHandle;
|
|
||||||
use async_executors::{Bindgen, LocalSpawnHandleExt /*, SpawnHandleExt*/};
|
use async_executors::{Bindgen, LocalSpawnHandleExt /*, SpawnHandleExt*/};
|
||||||
use core::fmt;
|
use core::fmt;
|
||||||
use futures_util::future::{select, Either};
|
use futures_util::future::{select, Either};
|
||||||
@ -105,23 +104,42 @@ pub fn system_boxed<'a, Out>(
|
|||||||
Box::pin(future)
|
Box::pin(future)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn<Out>(future: impl Future<Output = Out> + 'static) -> JoinHandle<Out>
|
pub fn spawn<Out>(future: impl Future<Output = Out> + 'static) -> MustJoinHandle<Out>
|
||||||
|
where
|
||||||
|
Out: Send + 'static,
|
||||||
|
{
|
||||||
|
MustJoinHandle::new(Bindgen
|
||||||
|
.spawn_handle_local(future)
|
||||||
|
.expect("wasm-bindgen-futures spawn should never error out"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_local<Out>(future: impl Future<Output = Out> + 'static) -> MustJoinHandle<Out>
|
||||||
|
where
|
||||||
|
Out: 'static,
|
||||||
|
{
|
||||||
|
MustJoinHandle::new(Bindgen
|
||||||
|
.spawn_handle_local(future)
|
||||||
|
.expect("wasm-bindgen-futures spawn_local should never error out"))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_with_local_set<Out>(
|
||||||
|
future: impl Future<Output = Out> + 'static,
|
||||||
|
) -> MustJoinHandle<Out>
|
||||||
|
where
|
||||||
|
Out: Send + 'static,
|
||||||
|
{
|
||||||
|
spawn(future)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn spawn_detached<Out>(future: impl Future<Output = Out> + 'static)
|
||||||
where
|
where
|
||||||
Out: Send + 'static,
|
Out: Send + 'static,
|
||||||
{
|
{
|
||||||
Bindgen
|
Bindgen
|
||||||
.spawn_handle_local(future)
|
.spawn_handle_local(future)
|
||||||
.expect("wasm-bindgen-futures spawn should never error out")
|
.expect("wasm-bindgen-futures spawn_local should never error out").detach()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn spawn_local<Out>(future: impl Future<Output = Out> + 'static) -> JoinHandle<Out>
|
|
||||||
where
|
|
||||||
Out: 'static,
|
|
||||||
{
|
|
||||||
Bindgen
|
|
||||||
.spawn_handle_local(future)
|
|
||||||
.expect("wasm-bindgen-futures spawn_local should never error out")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn interval<F, FUT>(freq_ms: u32, callback: F) -> SystemPinBoxFuture<()>
|
pub fn interval<F, FUT>(freq_ms: u32, callback: F) -> SystemPinBoxFuture<()>
|
||||||
where
|
where
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use crate::intf::table_db::*;
|
use crate::intf::table_db::*;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use keyvaluedb_web::*;
|
use keyvaluedb_web::*;
|
||||||
|
|
||||||
|
@ -1,9 +1,19 @@
|
|||||||
#![deny(clippy::all)]
|
#![deny(clippy::all)]
|
||||||
#![deny(unused_must_use)]
|
#![deny(unused_must_use)]
|
||||||
#[cfg(all(feature = "rt-async-std", feature = "rt-tokio"))]
|
|
||||||
compile_error!(
|
cfg_if::cfg_if! {
|
||||||
"feature \"rt-async-std\" and feature \"rt-tokio\" cannot be enabled at the same time"
|
if #[cfg(target_arch = "wasm32")] {
|
||||||
);
|
#[cfg(any(feature = "rt-async-std", feature = "rt-tokio"))]
|
||||||
|
compile_error!("features \"rt-async-std\" and \"rt-tokio\" can not be specified for WASM");
|
||||||
|
} else {
|
||||||
|
#[cfg(all(feature = "rt-async-std", feature = "rt-tokio"))]
|
||||||
|
compile_error!(
|
||||||
|
"feature \"rt-async-std\" and feature \"rt-tokio\" cannot be enabled at the same time"
|
||||||
|
);
|
||||||
|
#[cfg(not(any(feature = "rt-async-std", feature = "rt-tokio")))]
|
||||||
|
compile_error!("exactly one of feature \"rt-async-std\" or feature \"rt-tokio\" must be specified");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
@ -51,7 +61,9 @@ pub fn veilid_version() -> (u32, u32, u32) {
|
|||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
pub use intf::utils::android::{veilid_core_setup_android, veilid_core_setup_android_no_log};
|
pub use intf::utils::android::{veilid_core_setup_android, veilid_core_setup_android_no_log};
|
||||||
|
|
||||||
pub static DEFAULT_LOG_IGNORE_LIST: [&str; 10] = [
|
pub static DEFAULT_LOG_IGNORE_LIST: [&str; 12] = [
|
||||||
|
"mio",
|
||||||
|
"serial_test",
|
||||||
"async_std",
|
"async_std",
|
||||||
"async_io",
|
"async_io",
|
||||||
"polling",
|
"polling",
|
||||||
|
@ -43,12 +43,12 @@ impl ConnectionManager {
|
|||||||
config: VeilidConfig,
|
config: VeilidConfig,
|
||||||
stop_source: StopSource,
|
stop_source: StopSource,
|
||||||
sender: flume::Sender<ConnectionManagerEvent>,
|
sender: flume::Sender<ConnectionManagerEvent>,
|
||||||
async_processor_jh: JoinHandle<()>,
|
async_processor_jh: MustJoinHandle<()>,
|
||||||
) -> ConnectionManagerInner {
|
) -> ConnectionManagerInner {
|
||||||
ConnectionManagerInner {
|
ConnectionManagerInner {
|
||||||
stop_source: Some(stop_source),
|
stop_source: Some(stop_source),
|
||||||
sender: sender,
|
sender: sender,
|
||||||
async_processor_jh: Some(MustJoinHandle::new(async_processor_jh)),
|
async_processor_jh: Some(async_processor_jh),
|
||||||
connection_table: ConnectionTable::new(config),
|
connection_table: ConnectionTable::new(config),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ mod protocol;
|
|||||||
mod start_protocols;
|
mod start_protocols;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::routing_table::*;
|
use crate::routing_table::*;
|
||||||
use connection_manager::*;
|
use connection_manager::*;
|
||||||
use network_tcp::*;
|
use network_tcp::*;
|
||||||
@ -15,10 +14,9 @@ use protocol::ws::WebsocketProtocolHandler;
|
|||||||
pub use protocol::*;
|
pub use protocol::*;
|
||||||
use utils::network_interfaces::*;
|
use utils::network_interfaces::*;
|
||||||
|
|
||||||
use async_std::io;
|
|
||||||
use async_std::net::*;
|
|
||||||
use async_tls::TlsAcceptor;
|
use async_tls::TlsAcceptor;
|
||||||
use futures_util::StreamExt;
|
use futures_util::StreamExt;
|
||||||
|
use std::io;
|
||||||
// xxx: rustls ^0.20
|
// xxx: rustls ^0.20
|
||||||
//use rustls::{server::NoClientAuth, Certificate, PrivateKey, ServerConfig};
|
//use rustls::{server::NoClientAuth, Certificate, PrivateKey, ServerConfig};
|
||||||
use rustls::{Certificate, NoClientAuth, PrivateKey, ServerConfig};
|
use rustls::{Certificate, NoClientAuth, PrivateKey, ServerConfig};
|
||||||
@ -26,7 +24,6 @@ use rustls_pemfile::{certs, pkcs8_private_keys, rsa_private_keys};
|
|||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::BufReader;
|
use std::io::BufReader;
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::time::Duration;
|
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -558,12 +555,13 @@ impl Network {
|
|||||||
let mut inner = self.inner.lock();
|
let mut inner = self.inner.lock();
|
||||||
// take the join handles out
|
// take the join handles out
|
||||||
for h in inner.join_handles.drain(..) {
|
for h in inner.join_handles.drain(..) {
|
||||||
|
trace!("joining: {:?}", h);
|
||||||
unord.push(h);
|
unord.push(h);
|
||||||
}
|
}
|
||||||
// Drop the stop
|
// Drop the stop
|
||||||
drop(inner.stop_source.take());
|
drop(inner.stop_source.take());
|
||||||
}
|
}
|
||||||
debug!("stopping {} low level network tasks", unord.len());
|
debug!("stopping {} low level network tasks", unord.len(),);
|
||||||
// Wait for everything to stop
|
// Wait for everything to stop
|
||||||
while unord.next().await.is_some() {}
|
while unord.next().await.is_some() {}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::intf::*;
|
|
||||||
use async_tls::TlsAcceptor;
|
use async_tls::TlsAcceptor;
|
||||||
use sockets::*;
|
use sockets::*;
|
||||||
use stop_token::future::FutureExt;
|
use stop_token::future::FutureExt;
|
||||||
@ -43,46 +42,41 @@ impl Network {
|
|||||||
&self,
|
&self,
|
||||||
tls_acceptor: &TlsAcceptor,
|
tls_acceptor: &TlsAcceptor,
|
||||||
stream: AsyncPeekStream,
|
stream: AsyncPeekStream,
|
||||||
tcp_stream: TcpStream,
|
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
protocol_handlers: &[Box<dyn ProtocolAcceptHandler>],
|
protocol_handlers: &[Box<dyn ProtocolAcceptHandler>],
|
||||||
tls_connection_initial_timeout: u64,
|
tls_connection_initial_timeout_ms: u32,
|
||||||
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
||||||
let ts = tls_acceptor
|
let tls_stream = tls_acceptor
|
||||||
.accept(stream)
|
.accept(stream)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!(debug "TLS stream failed handshake"))?;
|
.map_err(logthru_net!(debug "TLS stream failed handshake"))?;
|
||||||
let ps = AsyncPeekStream::new(CloneStream::new(ts));
|
let ps = AsyncPeekStream::new(tls_stream);
|
||||||
let mut first_packet = [0u8; PEEK_DETECT_LEN];
|
let mut first_packet = [0u8; PEEK_DETECT_LEN];
|
||||||
|
|
||||||
// Try the handlers but first get a chunk of data for them to process
|
// Try the handlers but first get a chunk of data for them to process
|
||||||
// Don't waste more than N seconds getting it though, in case someone
|
// Don't waste more than N seconds getting it though, in case someone
|
||||||
// is trying to DoS us with a bunch of connections or something
|
// is trying to DoS us with a bunch of connections or something
|
||||||
// read a chunk of the stream
|
// read a chunk of the stream
|
||||||
io::timeout(
|
intf::timeout(
|
||||||
Duration::from_micros(tls_connection_initial_timeout),
|
tls_connection_initial_timeout_ms,
|
||||||
ps.peek_exact(&mut first_packet),
|
ps.peek_exact(&mut first_packet),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
|
.map_err(map_to_string)?
|
||||||
.map_err(map_to_string)?;
|
.map_err(map_to_string)?;
|
||||||
|
|
||||||
self.try_handlers(ps, tcp_stream, addr, protocol_handlers)
|
self.try_handlers(ps, addr, protocol_handlers).await
|
||||||
.await
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn try_handlers(
|
async fn try_handlers(
|
||||||
&self,
|
&self,
|
||||||
stream: AsyncPeekStream,
|
stream: AsyncPeekStream,
|
||||||
tcp_stream: TcpStream,
|
|
||||||
addr: SocketAddr,
|
addr: SocketAddr,
|
||||||
protocol_accept_handlers: &[Box<dyn ProtocolAcceptHandler>],
|
protocol_accept_handlers: &[Box<dyn ProtocolAcceptHandler>],
|
||||||
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
||||||
for ah in protocol_accept_handlers.iter() {
|
for ah in protocol_accept_handlers.iter() {
|
||||||
if let Some(nc) = ah
|
if let Some(nc) = ah.on_accept(stream.clone(), addr).await? {
|
||||||
.on_accept(stream.clone(), tcp_stream.clone(), addr)
|
|
||||||
.await?
|
|
||||||
{
|
|
||||||
return Ok(Some(nc));
|
return Ok(Some(nc));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -92,11 +86,11 @@ impl Network {
|
|||||||
|
|
||||||
async fn tcp_acceptor(
|
async fn tcp_acceptor(
|
||||||
self,
|
self,
|
||||||
tcp_stream: async_std::io::Result<TcpStream>,
|
tcp_stream: io::Result<TcpStream>,
|
||||||
listener_state: Arc<RwLock<ListenerState>>,
|
listener_state: Arc<RwLock<ListenerState>>,
|
||||||
connection_manager: ConnectionManager,
|
connection_manager: ConnectionManager,
|
||||||
connection_initial_timeout: u64,
|
connection_initial_timeout_ms: u32,
|
||||||
tls_connection_initial_timeout: u64,
|
tls_connection_initial_timeout_ms: u32,
|
||||||
) {
|
) {
|
||||||
let tcp_stream = match tcp_stream {
|
let tcp_stream = match tcp_stream {
|
||||||
Ok(v) => v,
|
Ok(v) => v,
|
||||||
@ -125,14 +119,16 @@ impl Network {
|
|||||||
log_net!("TCP connection from: {}", addr);
|
log_net!("TCP connection from: {}", addr);
|
||||||
|
|
||||||
// Create a stream we can peek on
|
// Create a stream we can peek on
|
||||||
let ps = AsyncPeekStream::new(tcp_stream.clone());
|
#[cfg(feature = "rt-tokio")]
|
||||||
|
let tcp_stream = tcp_stream.compat();
|
||||||
|
let ps = AsyncPeekStream::new(tcp_stream);
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////
|
||||||
let mut first_packet = [0u8; PEEK_DETECT_LEN];
|
let mut first_packet = [0u8; PEEK_DETECT_LEN];
|
||||||
|
|
||||||
// read a chunk of the stream
|
// read a chunk of the stream
|
||||||
if io::timeout(
|
if timeout(
|
||||||
Duration::from_micros(connection_initial_timeout),
|
connection_initial_timeout_ms,
|
||||||
ps.peek_exact(&mut first_packet),
|
ps.peek_exact(&mut first_packet),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@ -153,14 +149,13 @@ impl Network {
|
|||||||
self.try_tls_handlers(
|
self.try_tls_handlers(
|
||||||
ls.tls_acceptor.as_ref().unwrap(),
|
ls.tls_acceptor.as_ref().unwrap(),
|
||||||
ps,
|
ps,
|
||||||
tcp_stream,
|
|
||||||
addr,
|
addr,
|
||||||
&ls.tls_protocol_handlers,
|
&ls.tls_protocol_handlers,
|
||||||
tls_connection_initial_timeout,
|
tls_connection_initial_timeout_ms,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
} else {
|
} else {
|
||||||
self.try_handlers(ps, tcp_stream, addr, &ls.protocol_accept_handlers)
|
self.try_handlers(ps, addr, &ls.protocol_accept_handlers)
|
||||||
.await
|
.await
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -192,11 +187,11 @@ impl Network {
|
|||||||
|
|
||||||
async fn spawn_socket_listener(&self, addr: SocketAddr) -> Result<(), String> {
|
async fn spawn_socket_listener(&self, addr: SocketAddr) -> Result<(), String> {
|
||||||
// Get config
|
// Get config
|
||||||
let (connection_initial_timeout, tls_connection_initial_timeout) = {
|
let (connection_initial_timeout_ms, tls_connection_initial_timeout_ms) = {
|
||||||
let c = self.config.get();
|
let c = self.config.get();
|
||||||
(
|
(
|
||||||
ms_to_us(c.network.connection_initial_timeout_ms),
|
c.network.connection_initial_timeout_ms,
|
||||||
ms_to_us(c.network.tls.connection_initial_timeout_ms),
|
c.network.tls.connection_initial_timeout_ms,
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -209,7 +204,13 @@ impl Network {
|
|||||||
|
|
||||||
// Make an async tcplistener from the socket2 socket
|
// Make an async tcplistener from the socket2 socket
|
||||||
let std_listener: std::net::TcpListener = socket.into();
|
let std_listener: std::net::TcpListener = socket.into();
|
||||||
let listener = TcpListener::from(std_listener);
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
let listener = TcpListener::from(std_listener);
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
let listener = TcpListener::from_std(std_listener).map_err(map_to_string)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
debug!("spawn_socket_listener: binding successful to {}", addr);
|
debug!("spawn_socket_listener: binding successful to {}", addr);
|
||||||
|
|
||||||
@ -229,8 +230,16 @@ impl Network {
|
|||||||
let jh = spawn(async move {
|
let jh = spawn(async move {
|
||||||
// moves listener object in and get incoming iterator
|
// moves listener object in and get incoming iterator
|
||||||
// when this task exists, the listener will close the socket
|
// when this task exists, the listener will close the socket
|
||||||
let _ = listener
|
|
||||||
.incoming()
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
let incoming_stream = listener.incoming();
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
let incoming_stream = tokio_stream::wrappers::TcpListenerStream::new(listener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = incoming_stream
|
||||||
.for_each_concurrent(None, |tcp_stream| {
|
.for_each_concurrent(None, |tcp_stream| {
|
||||||
let this = this.clone();
|
let this = this.clone();
|
||||||
let listener_state = listener_state.clone();
|
let listener_state = listener_state.clone();
|
||||||
@ -240,8 +249,8 @@ impl Network {
|
|||||||
tcp_stream,
|
tcp_stream,
|
||||||
listener_state,
|
listener_state,
|
||||||
connection_manager,
|
connection_manager,
|
||||||
connection_initial_timeout,
|
connection_initial_timeout_ms,
|
||||||
tls_connection_initial_timeout,
|
tls_connection_initial_timeout_ms,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.timeout_at(stop_token)
|
.timeout_at(stop_token)
|
||||||
@ -255,7 +264,7 @@ impl Network {
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Add to join handles
|
// Add to join handles
|
||||||
self.add_to_join_handles(MustJoinHandle::new(jh));
|
self.add_to_join_handles(jh);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ impl Network {
|
|||||||
// Run thread task to process stream of messages
|
// Run thread task to process stream of messages
|
||||||
let this = self.clone();
|
let this = self.clone();
|
||||||
|
|
||||||
let jh = spawn(async move {
|
let jh = spawn_with_local_set(async move {
|
||||||
trace!("UDP listener task spawned");
|
trace!("UDP listener task spawned");
|
||||||
|
|
||||||
// Collect all our protocol handlers into a vector
|
// Collect all our protocol handlers into a vector
|
||||||
@ -49,7 +49,7 @@ impl Network {
|
|||||||
for ph in protocol_handlers {
|
for ph in protocol_handlers {
|
||||||
let network_manager = network_manager.clone();
|
let network_manager = network_manager.clone();
|
||||||
let stop_token = stop_token.clone();
|
let stop_token = stop_token.clone();
|
||||||
let jh = spawn_local(async move {
|
let jh = intf::spawn_local(async move {
|
||||||
let mut data = vec![0u8; 65536];
|
let mut data = vec![0u8; 65536];
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@ -112,7 +112,7 @@ impl Network {
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
// Add to join handle
|
// Add to join handle
|
||||||
self.add_to_join_handles(MustJoinHandle::new(jh));
|
self.add_to_join_handles(jh);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -134,7 +134,13 @@ impl Network {
|
|||||||
|
|
||||||
// Make an async UdpSocket from the socket2 socket
|
// Make an async UdpSocket from the socket2 socket
|
||||||
let std_udp_socket: std::net::UdpSocket = socket.into();
|
let std_udp_socket: std::net::UdpSocket = socket.into();
|
||||||
let udp_socket = UdpSocket::from(std_udp_socket);
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
let udp_socket = UdpSocket::from(std_udp_socket);
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
let udp_socket = UdpSocket::from_std(std_udp_socket).map_err(map_to_string)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
let socket_arc = Arc::new(udp_socket);
|
let socket_arc = Arc::new(udp_socket);
|
||||||
|
|
||||||
// Create protocol handler
|
// Create protocol handler
|
||||||
@ -148,7 +154,13 @@ impl Network {
|
|||||||
if let Ok(socket) = new_bound_shared_udp_socket(socket_addr_v6) {
|
if let Ok(socket) = new_bound_shared_udp_socket(socket_addr_v6) {
|
||||||
// Make an async UdpSocket from the socket2 socket
|
// Make an async UdpSocket from the socket2 socket
|
||||||
let std_udp_socket: std::net::UdpSocket = socket.into();
|
let std_udp_socket: std::net::UdpSocket = socket.into();
|
||||||
let udp_socket = UdpSocket::from(std_udp_socket);
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
let udp_socket = UdpSocket::from(std_udp_socket);
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
let udp_socket = UdpSocket::from_std(std_udp_socket).map_err(map_to_string)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
let socket_arc = Arc::new(udp_socket);
|
let socket_arc = Arc::new(udp_socket);
|
||||||
|
|
||||||
// Create protocol handler
|
// Create protocol handler
|
||||||
@ -168,7 +180,13 @@ impl Network {
|
|||||||
|
|
||||||
// Make an async UdpSocket from the socket2 socket
|
// Make an async UdpSocket from the socket2 socket
|
||||||
let std_udp_socket: std::net::UdpSocket = socket.into();
|
let std_udp_socket: std::net::UdpSocket = socket.into();
|
||||||
let udp_socket = UdpSocket::from(std_udp_socket);
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
let udp_socket = UdpSocket::from(std_udp_socket);
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
let udp_socket = UdpSocket::from_std(std_udp_socket).map_err(map_to_string)?;
|
||||||
|
}
|
||||||
|
}
|
||||||
let socket_arc = Arc::new(udp_socket);
|
let socket_arc = Arc::new(udp_socket);
|
||||||
|
|
||||||
// Create protocol handler
|
// Create protocol handler
|
||||||
|
@ -92,15 +92,15 @@ impl ProtocolNetworkConnection {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn close(&self) -> Result<(), String> {
|
// pub async fn close(&self) -> Result<(), String> {
|
||||||
match self {
|
// match self {
|
||||||
Self::Dummy(d) => d.close(),
|
// Self::Dummy(d) => d.close(),
|
||||||
Self::RawTcp(t) => t.close().await,
|
// Self::RawTcp(t) => t.close().await,
|
||||||
Self::WsAccepted(w) => w.close().await,
|
// Self::WsAccepted(w) => w.close().await,
|
||||||
Self::Ws(w) => w.close().await,
|
// Self::Ws(w) => w.close().await,
|
||||||
Self::Wss(w) => w.close().await,
|
// Self::Wss(w) => w.close().await,
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||||
match self {
|
match self {
|
||||||
|
@ -1,7 +1,15 @@
|
|||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
use async_io::Async;
|
use async_io::Async;
|
||||||
use async_std::net::TcpStream;
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
pub use async_std::net::{TcpStream, TcpListener, Shutdown, UdpSocket};
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
pub use tokio::net::{TcpStream, TcpListener, UdpSocket};
|
||||||
|
pub use tokio_util::compat::*;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
|
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
|
||||||
|
|
||||||
cfg_if! {
|
cfg_if! {
|
||||||
@ -218,5 +226,11 @@ pub async fn nonblocking_connect(socket: Socket, addr: SocketAddr) -> std::io::R
|
|||||||
}?;
|
}?;
|
||||||
|
|
||||||
// Convert back to inner and then return async version
|
// Convert back to inner and then return async version
|
||||||
Ok(TcpStream::from(async_stream.into_inner()?))
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
Ok(TcpStream::from(async_stream.into_inner()?))
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
Ok(TcpStream::from_std(async_stream.into_inner()?)?)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ use sockets::*;
|
|||||||
pub struct RawTcpNetworkConnection {
|
pub struct RawTcpNetworkConnection {
|
||||||
descriptor: ConnectionDescriptor,
|
descriptor: ConnectionDescriptor,
|
||||||
stream: AsyncPeekStream,
|
stream: AsyncPeekStream,
|
||||||
tcp_stream: TcpStream,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for RawTcpNetworkConnection {
|
impl fmt::Debug for RawTcpNetworkConnection {
|
||||||
@ -15,31 +14,33 @@ impl fmt::Debug for RawTcpNetworkConnection {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl RawTcpNetworkConnection {
|
impl RawTcpNetworkConnection {
|
||||||
pub fn new(
|
pub fn new(descriptor: ConnectionDescriptor, stream: AsyncPeekStream) -> Self {
|
||||||
descriptor: ConnectionDescriptor,
|
Self { descriptor, stream }
|
||||||
stream: AsyncPeekStream,
|
|
||||||
tcp_stream: TcpStream,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
|
||||||
descriptor,
|
|
||||||
stream,
|
|
||||||
tcp_stream,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn descriptor(&self) -> ConnectionDescriptor {
|
pub fn descriptor(&self) -> ConnectionDescriptor {
|
||||||
self.descriptor.clone()
|
self.descriptor.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", err, skip(self))]
|
// #[instrument(level = "trace", err, skip(self))]
|
||||||
pub async fn close(&self) -> Result<(), String> {
|
// pub async fn close(&mut self) -> Result<(), String> {
|
||||||
// Make an attempt to flush the stream
|
// // Make an attempt to flush the stream
|
||||||
self.stream.clone().close().await.map_err(map_to_string)?;
|
// self.stream.clone().close().await.map_err(map_to_string)?;
|
||||||
// Then forcibly close the socket
|
// // Then shut down the write side of the socket to effect a clean close
|
||||||
self.tcp_stream
|
// cfg_if! {
|
||||||
.shutdown(Shutdown::Both)
|
// if #[cfg(feature="rt-async-std")] {
|
||||||
.map_err(map_to_string)
|
// self.tcp_stream
|
||||||
}
|
// .shutdown(async_std::net::Shutdown::Write)
|
||||||
|
// .map_err(map_to_string)
|
||||||
|
// } else if #[cfg(feature="rt-tokio")] {
|
||||||
|
// use tokio::io::AsyncWriteExt;
|
||||||
|
// self.tcp_stream.get_mut()
|
||||||
|
// .shutdown()
|
||||||
|
// .await
|
||||||
|
// .map_err(map_to_string)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
async fn send_internal(stream: &mut AsyncPeekStream, message: Vec<u8>) -> Result<(), String> {
|
async fn send_internal(stream: &mut AsyncPeekStream, message: Vec<u8>) -> Result<(), String> {
|
||||||
log_net!("sending TCP message of size {}", message.len());
|
log_net!("sending TCP message of size {}", message.len());
|
||||||
@ -115,11 +116,10 @@ impl RawTcpProtocolHandler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", err, skip(self, stream, tcp_stream))]
|
#[instrument(level = "trace", err, skip(self, stream))]
|
||||||
async fn on_accept_async(
|
async fn on_accept_async(
|
||||||
self,
|
self,
|
||||||
stream: AsyncPeekStream,
|
stream: AsyncPeekStream,
|
||||||
tcp_stream: TcpStream,
|
|
||||||
socket_addr: SocketAddr,
|
socket_addr: SocketAddr,
|
||||||
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
||||||
log_net!("TCP: on_accept_async: enter");
|
log_net!("TCP: on_accept_async: enter");
|
||||||
@ -139,7 +139,6 @@ impl RawTcpProtocolHandler {
|
|||||||
let conn = ProtocolNetworkConnection::RawTcp(RawTcpNetworkConnection::new(
|
let conn = ProtocolNetworkConnection::RawTcp(RawTcpNetworkConnection::new(
|
||||||
ConnectionDescriptor::new(peer_addr, SocketAddress::from_socket_addr(local_address)),
|
ConnectionDescriptor::new(peer_addr, SocketAddress::from_socket_addr(local_address)),
|
||||||
stream,
|
stream,
|
||||||
tcp_stream,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
log_net!(debug "TCP: on_accept_async from: {}", socket_addr);
|
log_net!(debug "TCP: on_accept_async from: {}", socket_addr);
|
||||||
@ -173,7 +172,9 @@ impl RawTcpProtocolHandler {
|
|||||||
.local_addr()
|
.local_addr()
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!("could not get local address from TCP stream"))?;
|
.map_err(logthru_net!("could not get local address from TCP stream"))?;
|
||||||
let ps = AsyncPeekStream::new(ts.clone());
|
#[cfg(feature = "rt-tokio")]
|
||||||
|
let ts = ts.compat();
|
||||||
|
let ps = AsyncPeekStream::new(ts);
|
||||||
|
|
||||||
// Wrap the stream in a network connection and return it
|
// Wrap the stream in a network connection and return it
|
||||||
let conn = ProtocolNetworkConnection::RawTcp(RawTcpNetworkConnection::new(
|
let conn = ProtocolNetworkConnection::RawTcp(RawTcpNetworkConnection::new(
|
||||||
@ -182,7 +183,6 @@ impl RawTcpProtocolHandler {
|
|||||||
SocketAddress::from_socket_addr(actual_local_address),
|
SocketAddress::from_socket_addr(actual_local_address),
|
||||||
),
|
),
|
||||||
ps,
|
ps,
|
||||||
ts,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
Ok(conn)
|
Ok(conn)
|
||||||
@ -216,7 +216,10 @@ impl RawTcpProtocolHandler {
|
|||||||
// .local_addr()
|
// .local_addr()
|
||||||
// .map_err(map_to_string)
|
// .map_err(map_to_string)
|
||||||
// .map_err(logthru_net!("could not get local address from TCP stream"))?;
|
// .map_err(logthru_net!("could not get local address from TCP stream"))?;
|
||||||
let mut ps = AsyncPeekStream::new(ts.clone());
|
|
||||||
|
#[cfg(feature = "rt-tokio")]
|
||||||
|
let ts = ts.compat();
|
||||||
|
let mut ps = AsyncPeekStream::new(ts);
|
||||||
|
|
||||||
// Send directly from the raw network connection
|
// Send directly from the raw network connection
|
||||||
// this builds the connection and tears it down immediately after the send
|
// this builds the connection and tears it down immediately after the send
|
||||||
@ -252,7 +255,9 @@ impl RawTcpProtocolHandler {
|
|||||||
// .local_addr()
|
// .local_addr()
|
||||||
// .map_err(map_to_string)
|
// .map_err(map_to_string)
|
||||||
// .map_err(logthru_net!("could not get local address from TCP stream"))?;
|
// .map_err(logthru_net!("could not get local address from TCP stream"))?;
|
||||||
let mut ps = AsyncPeekStream::new(ts.clone());
|
#[cfg(feature = "rt-tokio")]
|
||||||
|
let ts = ts.compat();
|
||||||
|
let mut ps = AsyncPeekStream::new(ts);
|
||||||
|
|
||||||
// Send directly from the raw network connection
|
// Send directly from the raw network connection
|
||||||
// this builds the connection and tears it down immediately after the send
|
// this builds the connection and tears it down immediately after the send
|
||||||
@ -271,9 +276,8 @@ impl ProtocolAcceptHandler for RawTcpProtocolHandler {
|
|||||||
fn on_accept(
|
fn on_accept(
|
||||||
&self,
|
&self,
|
||||||
stream: AsyncPeekStream,
|
stream: AsyncPeekStream,
|
||||||
tcp_stream: TcpStream,
|
|
||||||
peer_addr: SocketAddr,
|
peer_addr: SocketAddr,
|
||||||
) -> SystemPinBoxFuture<core::result::Result<Option<ProtocolNetworkConnection>, String>> {
|
) -> SystemPinBoxFuture<core::result::Result<Option<ProtocolNetworkConnection>, String>> {
|
||||||
Box::pin(self.clone().on_accept_async(stream, tcp_stream, peer_addr))
|
Box::pin(self.clone().on_accept_async(stream, peer_addr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
use sockets::*;
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RawUdpProtocolHandler {
|
pub struct RawUdpProtocolHandler {
|
||||||
|
@ -1,28 +1,35 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use async_std::io;
|
|
||||||
use async_tls::TlsConnector;
|
use async_tls::TlsConnector;
|
||||||
use async_tungstenite::tungstenite::protocol::Message;
|
use async_tungstenite::tungstenite::protocol::Message;
|
||||||
use async_tungstenite::{accept_async, client_async, WebSocketStream};
|
use async_tungstenite::{accept_async, client_async, WebSocketStream};
|
||||||
use futures_util::SinkExt;
|
use futures_util::{AsyncRead, AsyncWrite, SinkExt};
|
||||||
use sockets::*;
|
use sockets::*;
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
pub type WebsocketNetworkConnectionWSS =
|
||||||
|
WebsocketNetworkConnection<async_tls::client::TlsStream<TcpStream>>;
|
||||||
|
pub type WebsocketNetworkConnectionWS = WebsocketNetworkConnection<TcpStream>;
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
pub type WebsocketNetworkConnectionWSS =
|
||||||
|
WebsocketNetworkConnection<async_tls::client::TlsStream<Compat<TcpStream>>>;
|
||||||
|
pub type WebsocketNetworkConnectionWS = WebsocketNetworkConnection<Compat<TcpStream>>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub type WebSocketNetworkConnectionAccepted = WebsocketNetworkConnection<AsyncPeekStream>;
|
pub type WebSocketNetworkConnectionAccepted = WebsocketNetworkConnection<AsyncPeekStream>;
|
||||||
pub type WebsocketNetworkConnectionWSS =
|
|
||||||
WebsocketNetworkConnection<async_tls::client::TlsStream<TcpStream>>;
|
|
||||||
pub type WebsocketNetworkConnectionWS = WebsocketNetworkConnection<TcpStream>;
|
|
||||||
|
|
||||||
pub struct WebsocketNetworkConnection<T>
|
pub struct WebsocketNetworkConnection<T>
|
||||||
where
|
where
|
||||||
T: io::Read + io::Write + Send + Unpin + 'static,
|
T: AsyncRead + AsyncWrite + Send + Unpin + 'static,
|
||||||
{
|
{
|
||||||
descriptor: ConnectionDescriptor,
|
descriptor: ConnectionDescriptor,
|
||||||
stream: CloneStream<WebSocketStream<T>>,
|
stream: CloneStream<WebSocketStream<T>>,
|
||||||
tcp_stream: TcpStream,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> fmt::Debug for WebsocketNetworkConnection<T>
|
impl<T> fmt::Debug for WebsocketNetworkConnection<T>
|
||||||
where
|
where
|
||||||
T: io::Read + io::Write + Send + Unpin + 'static,
|
T: AsyncRead + AsyncWrite + Send + Unpin + 'static,
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
write!(f, "{}", std::any::type_name::<Self>())
|
write!(f, "{}", std::any::type_name::<Self>())
|
||||||
@ -31,17 +38,12 @@ where
|
|||||||
|
|
||||||
impl<T> WebsocketNetworkConnection<T>
|
impl<T> WebsocketNetworkConnection<T>
|
||||||
where
|
where
|
||||||
T: io::Read + io::Write + Send + Unpin + 'static,
|
T: AsyncRead + AsyncWrite + Send + Unpin + 'static,
|
||||||
{
|
{
|
||||||
pub fn new(
|
pub fn new(descriptor: ConnectionDescriptor, stream: WebSocketStream<T>) -> Self {
|
||||||
descriptor: ConnectionDescriptor,
|
|
||||||
stream: WebSocketStream<T>,
|
|
||||||
tcp_stream: TcpStream,
|
|
||||||
) -> Self {
|
|
||||||
Self {
|
Self {
|
||||||
descriptor,
|
descriptor,
|
||||||
stream: CloneStream::new(stream),
|
stream: CloneStream::new(stream),
|
||||||
tcp_stream,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,15 +51,15 @@ where
|
|||||||
self.descriptor.clone()
|
self.descriptor.clone()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", err, skip(self))]
|
// #[instrument(level = "trace", err, skip(self))]
|
||||||
pub async fn close(&self) -> Result<(), String> {
|
// pub async fn close(&self) -> Result<(), String> {
|
||||||
// Make an attempt to flush the stream
|
// // Make an attempt to flush the stream
|
||||||
self.stream.clone().close().await.map_err(map_to_string)?;
|
// self.stream.clone().close().await.map_err(map_to_string)?;
|
||||||
// Then forcibly close the socket
|
// // Then forcibly close the socket
|
||||||
self.tcp_stream
|
// self.tcp_stream
|
||||||
.shutdown(Shutdown::Both)
|
// .shutdown(Shutdown::Both)
|
||||||
.map_err(map_to_string)
|
// .map_err(map_to_string)
|
||||||
}
|
// }
|
||||||
|
|
||||||
#[instrument(level = "trace", err, skip(self, message), fields(message.len = message.len()))]
|
#[instrument(level = "trace", err, skip(self, message), fields(message.len = message.len()))]
|
||||||
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
pub async fn send(&self, message: Vec<u8>) -> Result<(), String> {
|
||||||
@ -101,7 +103,7 @@ struct WebsocketProtocolHandlerArc {
|
|||||||
tls: bool,
|
tls: bool,
|
||||||
local_address: SocketAddr,
|
local_address: SocketAddr,
|
||||||
request_path: Vec<u8>,
|
request_path: Vec<u8>,
|
||||||
connection_initial_timeout: u64,
|
connection_initial_timeout_ms: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
@ -119,10 +121,10 @@ impl WebsocketProtocolHandler {
|
|||||||
} else {
|
} else {
|
||||||
format!("GET /{}", c.network.protocol.wss.path.trim_end_matches('/'))
|
format!("GET /{}", c.network.protocol.wss.path.trim_end_matches('/'))
|
||||||
};
|
};
|
||||||
let connection_initial_timeout = if tls {
|
let connection_initial_timeout_ms = if tls {
|
||||||
ms_to_us(c.network.tls.connection_initial_timeout_ms)
|
c.network.tls.connection_initial_timeout_ms
|
||||||
} else {
|
} else {
|
||||||
ms_to_us(c.network.connection_initial_timeout_ms)
|
c.network.connection_initial_timeout_ms
|
||||||
};
|
};
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
@ -130,34 +132,30 @@ impl WebsocketProtocolHandler {
|
|||||||
tls,
|
tls,
|
||||||
local_address,
|
local_address,
|
||||||
request_path: path.as_bytes().to_vec(),
|
request_path: path.as_bytes().to_vec(),
|
||||||
connection_initial_timeout,
|
connection_initial_timeout_ms,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[instrument(level = "trace", err, skip(self, ps, tcp_stream))]
|
#[instrument(level = "trace", err, skip(self, ps))]
|
||||||
pub async fn on_accept_async(
|
pub async fn on_accept_async(
|
||||||
self,
|
self,
|
||||||
ps: AsyncPeekStream,
|
ps: AsyncPeekStream,
|
||||||
tcp_stream: TcpStream,
|
|
||||||
socket_addr: SocketAddr,
|
socket_addr: SocketAddr,
|
||||||
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
) -> Result<Option<ProtocolNetworkConnection>, String> {
|
||||||
log_net!("WS: on_accept_async: enter");
|
log_net!("WS: on_accept_async: enter");
|
||||||
let request_path_len = self.arc.request_path.len() + 2;
|
let request_path_len = self.arc.request_path.len() + 2;
|
||||||
|
|
||||||
let mut peekbuf: Vec<u8> = vec![0u8; request_path_len];
|
let mut peekbuf: Vec<u8> = vec![0u8; request_path_len];
|
||||||
match io::timeout(
|
match timeout(
|
||||||
Duration::from_micros(self.arc.connection_initial_timeout),
|
self.arc.connection_initial_timeout_ms,
|
||||||
ps.peek_exact(&mut peekbuf),
|
ps.peek_exact(&mut peekbuf),
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
if e.kind() == io::ErrorKind::TimedOut {
|
return Err(e.to_string());
|
||||||
return Err(e).map_err(map_to_string);
|
|
||||||
}
|
|
||||||
return Err(e).map_err(map_to_string);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,7 +192,6 @@ impl WebsocketProtocolHandler {
|
|||||||
SocketAddress::from_socket_addr(self.arc.local_address),
|
SocketAddress::from_socket_addr(self.arc.local_address),
|
||||||
),
|
),
|
||||||
ws_stream,
|
ws_stream,
|
||||||
tcp_stream,
|
|
||||||
));
|
));
|
||||||
|
|
||||||
log_net!(debug "{}: on_accept_async from: {}", if self.arc.tls { "WSS" } else { "WS" }, socket_addr);
|
log_net!(debug "{}: on_accept_async from: {}", if self.arc.tls { "WSS" } else { "WS" }, socket_addr);
|
||||||
@ -238,6 +235,9 @@ impl WebsocketProtocolHandler {
|
|||||||
// See what local address we ended up with
|
// See what local address we ended up with
|
||||||
let actual_local_addr = tcp_stream.local_addr().map_err(map_to_string)?;
|
let actual_local_addr = tcp_stream.local_addr().map_err(map_to_string)?;
|
||||||
|
|
||||||
|
#[cfg(feature = "rt-tokio")]
|
||||||
|
let tcp_stream = tcp_stream.compat();
|
||||||
|
|
||||||
// Make our connection descriptor
|
// Make our connection descriptor
|
||||||
let descriptor = ConnectionDescriptor::new(
|
let descriptor = ConnectionDescriptor::new(
|
||||||
dial_info.to_peer_address(),
|
dial_info.to_peer_address(),
|
||||||
@ -247,7 +247,7 @@ impl WebsocketProtocolHandler {
|
|||||||
if tls {
|
if tls {
|
||||||
let connector = TlsConnector::default();
|
let connector = TlsConnector::default();
|
||||||
let tls_stream = connector
|
let tls_stream = connector
|
||||||
.connect(domain.to_string(), tcp_stream.clone())
|
.connect(domain.to_string(), tcp_stream)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!(error))?;
|
.map_err(logthru_net!(error))?;
|
||||||
@ -257,15 +257,15 @@ impl WebsocketProtocolHandler {
|
|||||||
.map_err(logthru_net!(error))?;
|
.map_err(logthru_net!(error))?;
|
||||||
|
|
||||||
Ok(ProtocolNetworkConnection::Wss(
|
Ok(ProtocolNetworkConnection::Wss(
|
||||||
WebsocketNetworkConnection::new(descriptor, ws_stream, tcp_stream),
|
WebsocketNetworkConnection::new(descriptor, ws_stream),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
let (ws_stream, _response) = client_async(request, tcp_stream.clone())
|
let (ws_stream, _response) = client_async(request, tcp_stream)
|
||||||
.await
|
.await
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!(error))?;
|
.map_err(logthru_net!(error))?;
|
||||||
Ok(ProtocolNetworkConnection::Ws(
|
Ok(ProtocolNetworkConnection::Ws(
|
||||||
WebsocketNetworkConnection::new(descriptor, ws_stream, tcp_stream),
|
WebsocketNetworkConnection::new(descriptor, ws_stream),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -319,9 +319,8 @@ impl ProtocolAcceptHandler for WebsocketProtocolHandler {
|
|||||||
fn on_accept(
|
fn on_accept(
|
||||||
&self,
|
&self,
|
||||||
stream: AsyncPeekStream,
|
stream: AsyncPeekStream,
|
||||||
tcp_stream: TcpStream,
|
|
||||||
peer_addr: SocketAddr,
|
peer_addr: SocketAddr,
|
||||||
) -> SystemPinBoxFuture<Result<Option<ProtocolNetworkConnection>, String>> {
|
) -> SystemPinBoxFuture<Result<Option<ProtocolNetworkConnection>, String>> {
|
||||||
Box::pin(self.clone().on_accept_async(stream, tcp_stream, peer_addr))
|
Box::pin(self.clone().on_accept_async(stream, peer_addr))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -319,7 +319,6 @@ impl Network {
|
|||||||
// Resolve statically configured public dialinfo
|
// Resolve statically configured public dialinfo
|
||||||
let mut public_sockaddrs = public_address
|
let mut public_sockaddrs = public_address
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
.await
|
|
||||||
.map_err(|e| format!("Unable to resolve address: {}\n{}", public_address, e))?;
|
.map_err(|e| format!("Unable to resolve address: {}\n{}", public_address, e))?;
|
||||||
|
|
||||||
// Add all resolved addresses as public dialinfo
|
// Add all resolved addresses as public dialinfo
|
||||||
@ -416,7 +415,6 @@ impl Network {
|
|||||||
let global_socket_addrs = split_url
|
let global_socket_addrs = split_url
|
||||||
.host_port(80)
|
.host_port(80)
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
.await
|
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!(error))?;
|
.map_err(logthru_net!(error))?;
|
||||||
|
|
||||||
@ -548,7 +546,6 @@ impl Network {
|
|||||||
let global_socket_addrs = split_url
|
let global_socket_addrs = split_url
|
||||||
.host_port(443)
|
.host_port(443)
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
.await
|
|
||||||
.map_err(map_to_string)
|
.map_err(map_to_string)
|
||||||
.map_err(logthru_net!(error))?;
|
.map_err(logthru_net!(error))?;
|
||||||
|
|
||||||
@ -662,7 +659,6 @@ impl Network {
|
|||||||
// Resolve statically configured public dialinfo
|
// Resolve statically configured public dialinfo
|
||||||
let mut public_sockaddrs = public_address
|
let mut public_sockaddrs = public_address
|
||||||
.to_socket_addrs()
|
.to_socket_addrs()
|
||||||
.await
|
|
||||||
.map_err(|e| format!("Unable to resolve address: {}\n{}", public_address, e))?;
|
.map_err(|e| format!("Unable to resolve address: {}\n{}", public_address, e))?;
|
||||||
|
|
||||||
// Add all resolved addresses as public dialinfo
|
// Add all resolved addresses as public dialinfo
|
||||||
|
@ -6,7 +6,6 @@ cfg_if::cfg_if! {
|
|||||||
if #[cfg(target_arch = "wasm32")] {
|
if #[cfg(target_arch = "wasm32")] {
|
||||||
// No accept support for WASM
|
// No accept support for WASM
|
||||||
} else {
|
} else {
|
||||||
use async_std::net::*;
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////
|
||||||
// Accept
|
// Accept
|
||||||
@ -15,7 +14,6 @@ cfg_if::cfg_if! {
|
|||||||
fn on_accept(
|
fn on_accept(
|
||||||
&self,
|
&self,
|
||||||
stream: AsyncPeekStream,
|
stream: AsyncPeekStream,
|
||||||
tcp_stream: TcpStream,
|
|
||||||
peer_addr: SocketAddr,
|
peer_addr: SocketAddr,
|
||||||
) -> SystemPinBoxFuture<Result<Option<ProtocolNetworkConnection>, String>>;
|
) -> SystemPinBoxFuture<Result<Option<ProtocolNetworkConnection>, String>>;
|
||||||
}
|
}
|
||||||
@ -139,7 +137,7 @@ impl NetworkConnection {
|
|||||||
let local_stop_token = stop_source.token();
|
let local_stop_token = stop_source.token();
|
||||||
|
|
||||||
// Spawn connection processor and pass in protocol connection
|
// Spawn connection processor and pass in protocol connection
|
||||||
let processor = MustJoinHandle::new(intf::spawn_local(Self::process_connection(
|
let processor = intf::spawn_local(Self::process_connection(
|
||||||
connection_manager,
|
connection_manager,
|
||||||
local_stop_token,
|
local_stop_token,
|
||||||
manager_stop_token,
|
manager_stop_token,
|
||||||
@ -148,7 +146,7 @@ impl NetworkConnection {
|
|||||||
protocol_connection,
|
protocol_connection,
|
||||||
inactivity_timeout,
|
inactivity_timeout,
|
||||||
stats.clone(),
|
stats.clone(),
|
||||||
)));
|
));
|
||||||
|
|
||||||
// Return the connection
|
// Return the connection
|
||||||
Self {
|
Self {
|
||||||
|
@ -82,7 +82,7 @@ impl Bucket {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|(k, v)| (k.clone(), v.clone()))
|
.map(|(k, v)| (k.clone(), v.clone()))
|
||||||
.collect();
|
.collect();
|
||||||
let cur_ts = get_timestamp();
|
let cur_ts = intf::get_timestamp();
|
||||||
sorted_entries.sort_by(|a, b| -> core::cmp::Ordering {
|
sorted_entries.sort_by(|a, b| -> core::cmp::Ordering {
|
||||||
if a.0 == b.0 {
|
if a.0 == b.0 {
|
||||||
return core::cmp::Ordering::Equal;
|
return core::cmp::Ordering::Equal;
|
||||||
|
@ -418,7 +418,7 @@ pub struct BucketEntry {
|
|||||||
|
|
||||||
impl BucketEntry {
|
impl BucketEntry {
|
||||||
pub(super) fn new() -> Self {
|
pub(super) fn new() -> Self {
|
||||||
let now = get_timestamp();
|
let now = intf::get_timestamp();
|
||||||
Self {
|
Self {
|
||||||
ref_count: AtomicU32::new(0),
|
ref_count: AtomicU32::new(0),
|
||||||
inner: RwLock::new(BucketEntryInner {
|
inner: RwLock::new(BucketEntryInner {
|
||||||
|
@ -89,7 +89,7 @@ impl RoutingTable {
|
|||||||
|
|
||||||
pub fn debug_info_entries(&self, limit: usize, min_state: BucketEntryState) -> String {
|
pub fn debug_info_entries(&self, limit: usize, min_state: BucketEntryState) -> String {
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
let cur_ts = get_timestamp();
|
let cur_ts = intf::get_timestamp();
|
||||||
|
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
|
|
||||||
@ -148,7 +148,7 @@ impl RoutingTable {
|
|||||||
|
|
||||||
pub fn debug_info_buckets(&self, min_state: BucketEntryState) -> String {
|
pub fn debug_info_buckets(&self, min_state: BucketEntryState) -> String {
|
||||||
let inner = self.inner.read();
|
let inner = self.inner.read();
|
||||||
let cur_ts = get_timestamp();
|
let cur_ts = intf::get_timestamp();
|
||||||
|
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
const COLS: usize = 16;
|
const COLS: usize = 16;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
use crate::dht::*;
|
use crate::dht::*;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
@ -219,7 +218,7 @@ impl RoutingTable {
|
|||||||
F: FnMut(DHTKey, Option<Arc<BucketEntry>>) -> bool,
|
F: FnMut(DHTKey, Option<Arc<BucketEntry>>) -> bool,
|
||||||
T: FnMut(DHTKey, Option<Arc<BucketEntry>>) -> O,
|
T: FnMut(DHTKey, Option<Arc<BucketEntry>>) -> O,
|
||||||
{
|
{
|
||||||
let cur_ts = get_timestamp();
|
let cur_ts = intf::get_timestamp();
|
||||||
let out = self.find_peers_with_sort_and_filter(
|
let out = self.find_peers_with_sort_and_filter(
|
||||||
node_count,
|
node_count,
|
||||||
cur_ts,
|
cur_ts,
|
||||||
@ -301,7 +300,7 @@ impl RoutingTable {
|
|||||||
T: FnMut(DHTKey, Option<Arc<BucketEntry>>) -> O,
|
T: FnMut(DHTKey, Option<Arc<BucketEntry>>) -> O,
|
||||||
F: FnMut(DHTKey, Option<Arc<BucketEntry>>) -> bool,
|
F: FnMut(DHTKey, Option<Arc<BucketEntry>>) -> bool,
|
||||||
{
|
{
|
||||||
let cur_ts = get_timestamp();
|
let cur_ts = intf::get_timestamp();
|
||||||
let node_count = {
|
let node_count = {
|
||||||
let c = self.config.get();
|
let c = self.config.get();
|
||||||
c.network.dht.max_find_node_count as usize
|
c.network.dht.max_find_node_count as usize
|
||||||
|
@ -7,7 +7,6 @@ mod stats_accounting;
|
|||||||
mod tasks;
|
mod tasks;
|
||||||
|
|
||||||
use crate::dht::*;
|
use crate::dht::*;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::network_manager::*;
|
use crate::network_manager::*;
|
||||||
use crate::rpc_processor::*;
|
use crate::rpc_processor::*;
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
|
@ -369,9 +369,7 @@ impl RoutingTable {
|
|||||||
Self::with_entries(&*inner, cur_ts, BucketEntryState::Unreliable, |k, v| {
|
Self::with_entries(&*inner, cur_ts, BucketEntryState::Unreliable, |k, v| {
|
||||||
if v.with(|e| e.needs_ping(&k, cur_ts, relay_node_id)) {
|
if v.with(|e| e.needs_ping(&k, cur_ts, relay_node_id)) {
|
||||||
let nr = NodeRef::new(self.clone(), k, v, None);
|
let nr = NodeRef::new(self.clone(), k, v, None);
|
||||||
unord.push(MustJoinHandle::new(intf::spawn_local(
|
unord.push(intf::spawn_local(rpc.clone().rpc_call_status(nr)));
|
||||||
rpc.clone().rpc_call_status(nr),
|
|
||||||
)));
|
|
||||||
}
|
}
|
||||||
Option::<()>::None
|
Option::<()>::None
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,6 @@ pub use debug::*;
|
|||||||
pub use private_route::*;
|
pub use private_route::*;
|
||||||
|
|
||||||
use crate::dht::*;
|
use crate::dht::*;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use capnp::message::ReaderSegments;
|
use capnp::message::ReaderSegments;
|
||||||
use coders::*;
|
use coders::*;
|
||||||
@ -228,7 +227,7 @@ impl RPCProcessor {
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
fn get_next_op_id(&self) -> OperationId {
|
fn get_next_op_id(&self) -> OperationId {
|
||||||
get_random_u64()
|
intf::get_random_u64()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_peer_scope(&self, node_info: &NodeInfo) -> bool {
|
fn filter_peer_scope(&self, node_info: &NodeInfo) -> bool {
|
||||||
@ -365,12 +364,12 @@ impl RPCProcessor {
|
|||||||
let timeout_ms = u32::try_from(waitable_reply.timeout / 1000u64)
|
let timeout_ms = u32::try_from(waitable_reply.timeout / 1000u64)
|
||||||
.map_err(map_error_internal!("invalid timeout"))?;
|
.map_err(map_error_internal!("invalid timeout"))?;
|
||||||
// wait for eventualvalue
|
// wait for eventualvalue
|
||||||
let start_ts = get_timestamp();
|
let start_ts = intf::get_timestamp();
|
||||||
let res = timeout(timeout_ms, waitable_reply.eventual.instance())
|
let res = intf::timeout(timeout_ms, waitable_reply.eventual.instance())
|
||||||
.await
|
.await
|
||||||
.map_err(|_| RPCError::Timeout)?;
|
.map_err(|_| RPCError::Timeout)?;
|
||||||
let rpcreader = res.take_value().unwrap();
|
let rpcreader = res.take_value().unwrap();
|
||||||
let end_ts = get_timestamp();
|
let end_ts = intf::get_timestamp();
|
||||||
Ok((rpcreader, end_ts - start_ts))
|
Ok((rpcreader, end_ts - start_ts))
|
||||||
}
|
}
|
||||||
async fn wait_for_reply(
|
async fn wait_for_reply(
|
||||||
@ -390,7 +389,7 @@ impl RPCProcessor {
|
|||||||
waitable_reply.node_ref.set_seen_our_node_info();
|
waitable_reply.node_ref.set_seen_our_node_info();
|
||||||
|
|
||||||
// Reply received
|
// Reply received
|
||||||
let recv_ts = get_timestamp();
|
let recv_ts = intf::get_timestamp();
|
||||||
self.routing_table().stats_answer_rcvd(
|
self.routing_table().stats_answer_rcvd(
|
||||||
waitable_reply.node_ref,
|
waitable_reply.node_ref,
|
||||||
waitable_reply.send_ts,
|
waitable_reply.send_ts,
|
||||||
@ -554,7 +553,7 @@ impl RPCProcessor {
|
|||||||
log_rpc!(debug "==>> REQUEST({}) -> {:?}", self.get_rpc_message_debug_info(&message), dest);
|
log_rpc!(debug "==>> REQUEST({}) -> {:?}", self.get_rpc_message_debug_info(&message), dest);
|
||||||
|
|
||||||
let bytes = out.len() as u64;
|
let bytes = out.len() as u64;
|
||||||
let send_ts = get_timestamp();
|
let send_ts = intf::get_timestamp();
|
||||||
let send_data_kind = match self
|
let send_data_kind = match self
|
||||||
.network_manager()
|
.network_manager()
|
||||||
.send_envelope(node_ref.clone(), Some(out_node_id), out)
|
.send_envelope(node_ref.clone(), Some(out_node_id), out)
|
||||||
@ -745,7 +744,7 @@ impl RPCProcessor {
|
|||||||
},
|
},
|
||||||
node_ref);
|
node_ref);
|
||||||
let bytes = out.len() as u64;
|
let bytes = out.len() as u64;
|
||||||
let send_ts = get_timestamp();
|
let send_ts = intf::get_timestamp();
|
||||||
self.network_manager()
|
self.network_manager()
|
||||||
.send_envelope(node_ref.clone(), Some(out_node_id), out)
|
.send_envelope(node_ref.clone(), Some(out_node_id), out)
|
||||||
.await
|
.await
|
||||||
@ -1399,7 +1398,7 @@ impl RPCProcessor {
|
|||||||
let mut timeout = ms_to_us(c.network.rpc.timeout_ms);
|
let mut timeout = ms_to_us(c.network.rpc.timeout_ms);
|
||||||
let mut max_route_hop_count = c.network.rpc.max_route_hop_count as usize;
|
let mut max_route_hop_count = c.network.rpc.max_route_hop_count as usize;
|
||||||
if concurrency == 0 {
|
if concurrency == 0 {
|
||||||
concurrency = get_concurrency() / 2;
|
concurrency = intf::get_concurrency() / 2;
|
||||||
if concurrency == 0 {
|
if concurrency == 0 {
|
||||||
concurrency = 1;
|
concurrency = 1;
|
||||||
}
|
}
|
||||||
@ -1424,8 +1423,8 @@ impl RPCProcessor {
|
|||||||
for _ in 0..concurrency {
|
for _ in 0..concurrency {
|
||||||
let this = self.clone();
|
let this = self.clone();
|
||||||
let receiver = channel.1.clone();
|
let receiver = channel.1.clone();
|
||||||
let jh = spawn(Self::rpc_worker(this, inner.stop_source.as_ref().unwrap().token(), receiver));
|
let jh = intf::spawn(Self::rpc_worker(this, inner.stop_source.as_ref().unwrap().token(), receiver));
|
||||||
inner.worker_join_handles.push(MustJoinHandle::new(jh));
|
inner.worker_join_handles.push(jh);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1466,7 +1465,7 @@ impl RPCProcessor {
|
|||||||
) -> Result<(), String> {
|
) -> Result<(), String> {
|
||||||
let msg = RPCMessage {
|
let msg = RPCMessage {
|
||||||
header: RPCMessageHeader {
|
header: RPCMessageHeader {
|
||||||
timestamp: get_timestamp(),
|
timestamp: intf::get_timestamp(),
|
||||||
envelope,
|
envelope,
|
||||||
body_len: body.len() as u64,
|
body_len: body.len() as u64,
|
||||||
peer_noderef,
|
peer_noderef,
|
||||||
|
@ -465,7 +465,8 @@ cfg_if! {
|
|||||||
let t1 = intf::get_timestamp();
|
let t1 = intf::get_timestamp();
|
||||||
let mut interfaces = intf::utils::network_interfaces::NetworkInterfaces::new();
|
let mut interfaces = intf::utils::network_interfaces::NetworkInterfaces::new();
|
||||||
let count = 100;
|
let count = 100;
|
||||||
for _ in 0..count {
|
for x in 0..count {
|
||||||
|
info!("loop {}", x);
|
||||||
if let Err(e) = interfaces.refresh().await {
|
if let Err(e) = interfaces.refresh().await {
|
||||||
error!("error refreshing interfaces: {}", e);
|
error!("error refreshing interfaces: {}", e);
|
||||||
}
|
}
|
||||||
@ -508,43 +509,6 @@ pub async fn test_get_random_u32() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn test_single_future() {
|
|
||||||
info!("testing single future");
|
|
||||||
let sf = SingleFuture::<u32>::new();
|
|
||||||
assert_eq!(sf.check().await, Ok(None));
|
|
||||||
assert_eq!(
|
|
||||||
sf.single_spawn(async {
|
|
||||||
intf::sleep(2000).await;
|
|
||||||
69
|
|
||||||
})
|
|
||||||
.await,
|
|
||||||
Ok((None, true))
|
|
||||||
);
|
|
||||||
assert_eq!(sf.check().await, Ok(None));
|
|
||||||
assert_eq!(sf.single_spawn(async { panic!() }).await, Ok((None, false)));
|
|
||||||
assert_eq!(sf.join().await, Ok(Some(69)));
|
|
||||||
assert_eq!(
|
|
||||||
sf.single_spawn(async {
|
|
||||||
intf::sleep(1000).await;
|
|
||||||
37
|
|
||||||
})
|
|
||||||
.await,
|
|
||||||
Ok((None, true))
|
|
||||||
);
|
|
||||||
intf::sleep(2000).await;
|
|
||||||
assert_eq!(
|
|
||||||
sf.single_spawn(async {
|
|
||||||
intf::sleep(1000).await;
|
|
||||||
27
|
|
||||||
})
|
|
||||||
.await,
|
|
||||||
Ok((Some(37), true))
|
|
||||||
);
|
|
||||||
intf::sleep(2000).await;
|
|
||||||
assert_eq!(sf.join().await, Ok(Some(27)));
|
|
||||||
assert_eq!(sf.check().await, Ok(None));
|
|
||||||
}
|
|
||||||
|
|
||||||
pub async fn test_must_join_single_future() {
|
pub async fn test_must_join_single_future() {
|
||||||
info!("testing must join single future");
|
info!("testing must join single future");
|
||||||
let sf = MustJoinSingleFuture::<u32>::new();
|
let sf = MustJoinSingleFuture::<u32>::new();
|
||||||
@ -604,7 +568,6 @@ pub async fn test_all() {
|
|||||||
test_sleep().await;
|
test_sleep().await;
|
||||||
#[cfg(not(target_arch = "wasm32"))]
|
#[cfg(not(target_arch = "wasm32"))]
|
||||||
test_network_interfaces().await;
|
test_network_interfaces().await;
|
||||||
test_single_future().await;
|
|
||||||
test_must_join_single_future().await;
|
test_must_join_single_future().await;
|
||||||
test_eventual().await;
|
test_eventual().await;
|
||||||
test_eventual_value().await;
|
test_eventual_value().await;
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use super::test_veilid_config::*;
|
use super::test_veilid_config::*;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
use super::test_veilid_config::*;
|
use super::test_veilid_config::*;
|
||||||
use crate::intf::*;
|
|
||||||
use crate::xx::*;
|
use crate::xx::*;
|
||||||
use crate::*;
|
use crate::*;
|
||||||
|
|
||||||
|
@ -69,53 +69,64 @@ pub fn run_all_tests() {
|
|||||||
info!("Finished unit tests");
|
info!("Finished unit tests");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rt-tokio")]
|
||||||
|
fn block_on<F: Future<Output = T>, T>(f: F) -> T {
|
||||||
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
let local = tokio::task::LocalSet::new();
|
||||||
|
local.block_on(&rt, f)
|
||||||
|
}
|
||||||
|
#[cfg(feature = "rt-async-std")]
|
||||||
|
fn block_on<F: Future<Output = T>, T>(f: F) -> T {
|
||||||
|
async_std::task::block_on(f)
|
||||||
|
}
|
||||||
|
|
||||||
fn exec_test_host_interface() {
|
fn exec_test_host_interface() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_host_interface::test_all().await;
|
test_host_interface::test_all().await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fn exec_test_dht_key() {
|
fn exec_test_dht_key() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_dht_key::test_all().await;
|
test_dht_key::test_all().await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fn exec_test_veilid_core() {
|
fn exec_test_veilid_core() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_veilid_core::test_all().await;
|
test_veilid_core::test_all().await;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fn exec_test_veilid_config() {
|
fn exec_test_veilid_config() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_veilid_config::test_all().await;
|
test_veilid_config::test_all().await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn exec_test_async_peek_stream() {
|
fn exec_test_async_peek_stream() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_async_peek_stream::test_all().await;
|
test_async_peek_stream::test_all().await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn exec_test_connection_table() {
|
fn exec_test_connection_table() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_connection_table::test_all().await;
|
test_connection_table::test_all().await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn exec_test_table_store() {
|
fn exec_test_table_store() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_table_store::test_all().await;
|
test_table_store::test_all().await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn exec_test_protected_store() {
|
fn exec_test_protected_store() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_protected_store::test_all().await;
|
test_protected_store::test_all().await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn exec_test_crypto() {
|
fn exec_test_crypto() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_crypto::test_all().await;
|
test_crypto::test_all().await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
fn exec_test_envelope_receipt() {
|
fn exec_test_envelope_receipt() {
|
||||||
async_std::task::block_on(async {
|
block_on(async {
|
||||||
test_envelope_receipt::test_all().await;
|
test_envelope_receipt::test_all().await;
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,17 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use async_std::net::{TcpListener, TcpStream};
|
|
||||||
use async_std::prelude::FutureExt;
|
cfg_if! {
|
||||||
use async_std::task;
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
use async_std::net::{TcpListener, TcpStream};
|
||||||
|
use async_std::prelude::FutureExt;
|
||||||
|
use async_std::task::sleep;
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
use tokio::net::{TcpListener, TcpStream};
|
||||||
|
use tokio::time::sleep;
|
||||||
|
use tokio_util::compat::*;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
use futures_util::{AsyncReadExt, AsyncWriteExt};
|
use futures_util::{AsyncReadExt, AsyncWriteExt};
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
@ -18,23 +28,40 @@ async fn make_tcp_loopback() -> Result<(TcpStream, TcpStream), io::Error> {
|
|||||||
Result::<TcpStream, io::Error>::Ok(accepted_stream)
|
Result::<TcpStream, io::Error>::Ok(accepted_stream)
|
||||||
};
|
};
|
||||||
let connect_future = async {
|
let connect_future = async {
|
||||||
task::sleep(Duration::from_secs(1)).await;
|
sleep(Duration::from_secs(1)).await;
|
||||||
let connected_stream = TcpStream::connect(local_addr).await?;
|
let connected_stream = TcpStream::connect(local_addr).await?;
|
||||||
connected_stream.set_nodelay(true)?;
|
connected_stream.set_nodelay(true)?;
|
||||||
Result::<TcpStream, io::Error>::Ok(connected_stream)
|
Result::<TcpStream, io::Error>::Ok(connected_stream)
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(accept_future.try_join(connect_future).await?)
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
accept_future.try_join(connect_future).await
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
tokio::try_join!(accept_future, connect_future)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn make_async_peek_stream_loopback() -> (AsyncPeekStream, AsyncPeekStream) {
|
async fn make_async_peek_stream_loopback() -> (AsyncPeekStream, AsyncPeekStream) {
|
||||||
let (acc, conn) = make_tcp_loopback().await.unwrap();
|
let (acc, conn) = make_tcp_loopback().await.unwrap();
|
||||||
|
#[cfg(feature = "rt-tokio")]
|
||||||
|
let acc = acc.compat();
|
||||||
|
#[cfg(feature = "rt-tokio")]
|
||||||
|
let conn = conn.compat();
|
||||||
|
|
||||||
let aps_a = AsyncPeekStream::new(acc);
|
let aps_a = AsyncPeekStream::new(acc);
|
||||||
let aps_c = AsyncPeekStream::new(conn);
|
let aps_c = AsyncPeekStream::new(conn);
|
||||||
|
|
||||||
(aps_a, aps_c)
|
(aps_a, aps_c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature = "rt-tokio")]
|
||||||
|
async fn make_stream_loopback() -> (Compat<TcpStream>, Compat<TcpStream>) {
|
||||||
|
let (a, c) = make_tcp_loopback().await.unwrap();
|
||||||
|
(a.compat(), c.compat())
|
||||||
|
}
|
||||||
|
#[cfg(feature = "rt-async-std")]
|
||||||
async fn make_stream_loopback() -> (TcpStream, TcpStream) {
|
async fn make_stream_loopback() -> (TcpStream, TcpStream) {
|
||||||
make_tcp_loopback().await.unwrap()
|
make_tcp_loopback().await.unwrap()
|
||||||
}
|
}
|
||||||
|
@ -1731,7 +1731,7 @@ impl fmt::Debug for VeilidAPIInner {
|
|||||||
impl Drop for VeilidAPIInner {
|
impl Drop for VeilidAPIInner {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if let Some(context) = self.context.take() {
|
if let Some(context) = self.context.take() {
|
||||||
intf::spawn_local(api_shutdown(context)).detach();
|
intf::spawn_detached(api_shutdown(context));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,17 +5,8 @@ use task::{Context, Poll};
|
|||||||
|
|
||||||
////////
|
////////
|
||||||
///
|
///
|
||||||
trait SendStream: AsyncRead + AsyncWrite + Send + Unpin {
|
trait SendStream: AsyncRead + AsyncWrite + Send + Unpin {}
|
||||||
fn clone_stream(&self) -> Box<dyn SendStream>;
|
impl<S> SendStream for S where S: AsyncRead + AsyncWrite + Send + Unpin + 'static {}
|
||||||
}
|
|
||||||
impl<S> SendStream for S
|
|
||||||
where
|
|
||||||
S: AsyncRead + AsyncWrite + Send + Clone + Unpin + 'static,
|
|
||||||
{
|
|
||||||
fn clone_stream(&self) -> Box<dyn SendStream> {
|
|
||||||
Box::new(self.clone())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
////////
|
////////
|
||||||
///
|
///
|
||||||
@ -126,7 +117,7 @@ where
|
|||||||
impl AsyncPeekStream {
|
impl AsyncPeekStream {
|
||||||
pub fn new<S>(stream: S) -> Self
|
pub fn new<S>(stream: S) -> Self
|
||||||
where
|
where
|
||||||
S: AsyncRead + AsyncWrite + Send + Clone + Unpin + 'static,
|
S: AsyncRead + AsyncWrite + Send + Unpin + 'static,
|
||||||
{
|
{
|
||||||
Self {
|
Self {
|
||||||
inner: Arc::new(Mutex::new(AsyncPeekStreamInner {
|
inner: Arc::new(Mutex::new(AsyncPeekStreamInner {
|
||||||
|
@ -11,7 +11,7 @@ mod log_thru;
|
|||||||
mod must_join_handle;
|
mod must_join_handle;
|
||||||
mod must_join_single_future;
|
mod must_join_single_future;
|
||||||
mod mutable_future;
|
mod mutable_future;
|
||||||
mod single_future;
|
// mod single_future;
|
||||||
mod single_shot_eventual;
|
mod single_shot_eventual;
|
||||||
mod split_url;
|
mod split_url;
|
||||||
mod tick_task;
|
mod tick_task;
|
||||||
@ -67,6 +67,7 @@ cfg_if! {
|
|||||||
pub use no_std_net::{ SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr };
|
pub use no_std_net::{ SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr };
|
||||||
pub type SystemPinBoxFuture<T> = PinBox<dyn Future<Output = T> + 'static>;
|
pub type SystemPinBoxFuture<T> = PinBox<dyn Future<Output = T> + 'static>;
|
||||||
pub type SystemPinBoxFutureLifetime<'a, T> = PinBox<dyn Future<Output = T> + 'a>;
|
pub type SystemPinBoxFutureLifetime<'a, T> = PinBox<dyn Future<Output = T> + 'a>;
|
||||||
|
pub use async_executors::JoinHandle as LowLevelJoinHandle;
|
||||||
} else {
|
} else {
|
||||||
pub use std::string::String;
|
pub use std::string::String;
|
||||||
pub use std::vec::Vec;
|
pub use std::vec::Vec;
|
||||||
@ -91,8 +92,17 @@ cfg_if! {
|
|||||||
pub use std::time::Duration;
|
pub use std::time::Duration;
|
||||||
pub use std::pin::Pin;
|
pub use std::pin::Pin;
|
||||||
pub use std::ops::{FnOnce, FnMut, Fn};
|
pub use std::ops::{FnOnce, FnMut, Fn};
|
||||||
pub use async_std::sync::Mutex as AsyncMutex;
|
cfg_if! {
|
||||||
pub use async_std::sync::MutexGuard as AsyncMutexGuard;
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
pub use async_std::sync::Mutex as AsyncMutex;
|
||||||
|
pub use async_std::sync::MutexGuard as AsyncMutexGuard;
|
||||||
|
pub use async_std::task::JoinHandle as LowLevelJoinHandle;
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
pub use tokio::sync::Mutex as AsyncMutex;
|
||||||
|
pub use tokio::sync::MutexGuard as AsyncMutexGuard;
|
||||||
|
pub use tokio::task::JoinHandle as LowLevelJoinHandle;
|
||||||
|
}
|
||||||
|
}
|
||||||
pub use std::net::{ SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr };
|
pub use std::net::{ SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs, IpAddr, Ipv4Addr, Ipv6Addr };
|
||||||
pub type SystemPinBoxFuture<T> = PinBox<dyn Future<Output = T> + Send + 'static>;
|
pub type SystemPinBoxFuture<T> = PinBox<dyn Future<Output = T> + Send + 'static>;
|
||||||
pub type SystemPinBoxFutureLifetime<'a, T> = PinBox<dyn Future<Output = T> + Send + 'a>;
|
pub type SystemPinBoxFutureLifetime<'a, T> = PinBox<dyn Future<Output = T> + Send + 'a>;
|
||||||
@ -111,7 +121,7 @@ pub use ip_extra::*;
|
|||||||
pub use must_join_handle::*;
|
pub use must_join_handle::*;
|
||||||
pub use must_join_single_future::*;
|
pub use must_join_single_future::*;
|
||||||
pub use mutable_future::*;
|
pub use mutable_future::*;
|
||||||
pub use single_future::*;
|
// pub use single_future::*;
|
||||||
pub use single_shot_eventual::*;
|
pub use single_shot_eventual::*;
|
||||||
pub use tick_task::*;
|
pub use tick_task::*;
|
||||||
pub use tools::*;
|
pub use tools::*;
|
||||||
|
@ -1,21 +1,40 @@
|
|||||||
use async_executors::JoinHandle;
|
use super::*;
|
||||||
use core::future::Future;
|
use core::future::Future;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
use core::task::{Context, Poll};
|
use core::task::{Context, Poll};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MustJoinHandle<T> {
|
pub struct MustJoinHandle<T> {
|
||||||
join_handle: JoinHandle<T>,
|
join_handle: Option<LowLevelJoinHandle<T>>,
|
||||||
completed: bool,
|
completed: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> MustJoinHandle<T> {
|
impl<T> MustJoinHandle<T> {
|
||||||
pub fn new(join_handle: JoinHandle<T>) -> Self {
|
pub fn new(join_handle: LowLevelJoinHandle<T>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
join_handle,
|
join_handle: Some(join_handle),
|
||||||
completed: false,
|
completed: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn abort(mut self) {
|
||||||
|
if !self.completed {
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
if let Some(jh) = self.join_handle.take() {
|
||||||
|
jh.cancel().await;
|
||||||
|
self.completed = true;
|
||||||
|
}
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
if let Some(jh) = self.join_handle.take() {
|
||||||
|
jh.abort();
|
||||||
|
let _ = jh.await;
|
||||||
|
self.completed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Drop for MustJoinHandle<T> {
|
impl<T> Drop for MustJoinHandle<T> {
|
||||||
@ -31,10 +50,16 @@ impl<T: 'static> Future for MustJoinHandle<T> {
|
|||||||
type Output = T;
|
type Output = T;
|
||||||
|
|
||||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
|
||||||
match Pin::new(&mut self.join_handle).poll(cx) {
|
match Pin::new(self.join_handle.as_mut().unwrap()).poll(cx) {
|
||||||
Poll::Ready(t) => {
|
Poll::Ready(t) => {
|
||||||
self.completed = true;
|
self.completed = true;
|
||||||
Poll::Ready(t)
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
Poll::Ready(t)
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
Poll::Ready(t.unwrap())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Poll::Pending => Poll::Pending,
|
Poll::Pending => Poll::Pending,
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::intf::*;
|
use crate::*;
|
||||||
use cfg_if::*;
|
|
||||||
use core::task::Poll;
|
use core::task::Poll;
|
||||||
use futures_util::poll;
|
use futures_util::poll;
|
||||||
|
|
||||||
@ -160,7 +159,7 @@ where
|
|||||||
|
|
||||||
// Run if we should do that
|
// Run if we should do that
|
||||||
if run {
|
if run {
|
||||||
self.unlock(Some(MustJoinHandle::new(spawn_local(future))));
|
self.unlock(Some(intf::spawn_local(future)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the prior result if we have one
|
// Return the prior result if we have one
|
||||||
@ -203,7 +202,7 @@ cfg_if! {
|
|||||||
}
|
}
|
||||||
// Run if we should do that
|
// Run if we should do that
|
||||||
if run {
|
if run {
|
||||||
self.unlock(Some(MustJoinHandle::new(spawn(future))));
|
self.unlock(Some(intf::spawn_with_local_set(future)));
|
||||||
}
|
}
|
||||||
// Return the prior result if we have one
|
// Return the prior result if we have one
|
||||||
Ok((out, run))
|
Ok((out, run))
|
||||||
|
@ -1,242 +0,0 @@
|
|||||||
use super::*;
|
|
||||||
use crate::intf::*;
|
|
||||||
use cfg_if::*;
|
|
||||||
use core::task::Poll;
|
|
||||||
use futures_util::poll;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
struct SingleFutureInner<T>
|
|
||||||
where
|
|
||||||
T: 'static,
|
|
||||||
{
|
|
||||||
locked: bool,
|
|
||||||
join_handle: Option<JoinHandle<T>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Spawns a single background processing task idempotently, possibly returning the return value of the previously executed background task
|
|
||||||
/// This does not queue, just ensures that no more than a single copy of the task is running at a time, but allowing tasks to be retriggered
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct SingleFuture<T>
|
|
||||||
where
|
|
||||||
T: 'static,
|
|
||||||
{
|
|
||||||
inner: Arc<Mutex<SingleFutureInner<T>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> Default for SingleFuture<T>
|
|
||||||
where
|
|
||||||
T: 'static,
|
|
||||||
{
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::new()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T> SingleFuture<T>
|
|
||||||
where
|
|
||||||
T: 'static,
|
|
||||||
{
|
|
||||||
pub fn new() -> Self {
|
|
||||||
Self {
|
|
||||||
inner: Arc::new(Mutex::new(SingleFutureInner {
|
|
||||||
locked: false,
|
|
||||||
join_handle: None,
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_lock(&self) -> Result<Option<JoinHandle<T>>, ()> {
|
|
||||||
let mut inner = self.inner.lock();
|
|
||||||
if inner.locked {
|
|
||||||
// If already locked error out
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
inner.locked = true;
|
|
||||||
// If we got the lock, return what we have for a join handle if anything
|
|
||||||
Ok(inner.join_handle.take())
|
|
||||||
}
|
|
||||||
|
|
||||||
fn unlock(&self, jh: Option<JoinHandle<T>>) {
|
|
||||||
let mut inner = self.inner.lock();
|
|
||||||
assert!(inner.locked);
|
|
||||||
assert!(inner.join_handle.is_none());
|
|
||||||
inner.locked = false;
|
|
||||||
inner.join_handle = jh;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the result
|
|
||||||
pub async fn check(&self) -> Result<Option<T>, ()> {
|
|
||||||
let mut out: Option<T> = None;
|
|
||||||
|
|
||||||
// See if we have a result we can return
|
|
||||||
let maybe_jh = match self.try_lock() {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => {
|
|
||||||
// If we are already polling somewhere else, don't hand back a result
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if maybe_jh.is_some() {
|
|
||||||
let mut jh = maybe_jh.unwrap();
|
|
||||||
|
|
||||||
// See if we finished, if so, return the value of the last execution
|
|
||||||
if let Poll::Ready(r) = poll!(&mut jh) {
|
|
||||||
out = Some(r);
|
|
||||||
// Task finished, unlock with nothing
|
|
||||||
self.unlock(None);
|
|
||||||
} else {
|
|
||||||
// Still running put the join handle back so we can check on it later
|
|
||||||
self.unlock(Some(jh));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// No task, unlock with nothing
|
|
||||||
self.unlock(None);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the prior result if we have one
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Wait for the result
|
|
||||||
pub async fn join(&self) -> Result<Option<T>, ()> {
|
|
||||||
let mut out: Option<T> = None;
|
|
||||||
|
|
||||||
// See if we have a result we can return
|
|
||||||
let maybe_jh = match self.try_lock() {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => {
|
|
||||||
// If we are already polling somewhere else,
|
|
||||||
// that's an error because you can only join
|
|
||||||
// these things once
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if maybe_jh.is_some() {
|
|
||||||
let jh = maybe_jh.unwrap();
|
|
||||||
// Wait for return value of the last execution
|
|
||||||
out = Some(jh.await);
|
|
||||||
// Task finished, unlock with nothing
|
|
||||||
} else {
|
|
||||||
// No task, unlock with nothing
|
|
||||||
}
|
|
||||||
self.unlock(None);
|
|
||||||
|
|
||||||
// Return the prior result if we have one
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel
|
|
||||||
pub async fn cancel(&self) -> Result<Option<T>, ()> {
|
|
||||||
let mut out: Option<T> = None;
|
|
||||||
|
|
||||||
// See if we have a result we can return
|
|
||||||
let maybe_jh = match self.try_lock() {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => {
|
|
||||||
// If we are already polling somewhere else, don't hand back a result
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if maybe_jh.is_some() {
|
|
||||||
let mut jh = maybe_jh.unwrap();
|
|
||||||
|
|
||||||
// See if we finished, if so, return the value of the last execution
|
|
||||||
if let Poll::Ready(r) = poll!(&mut jh) {
|
|
||||||
out = Some(r);
|
|
||||||
// Task finished, unlock with nothing
|
|
||||||
} else {
|
|
||||||
// Still running but drop the join handle anyway to cancel the task, unlock with nothing
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.unlock(None);
|
|
||||||
|
|
||||||
// Return the prior result if we have one
|
|
||||||
Ok(out)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Possibly spawn the future possibly returning the value of the last execution
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(target_arch = "wasm32")] {
|
|
||||||
pub async fn single_spawn(
|
|
||||||
&self,
|
|
||||||
future: impl Future<Output = T> + 'static,
|
|
||||||
) -> Result<(Option<T>, bool), ()> {
|
|
||||||
let mut out: Option<T> = None;
|
|
||||||
|
|
||||||
// See if we have a result we can return
|
|
||||||
let maybe_jh = match self.try_lock() {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => {
|
|
||||||
// If we are already polling somewhere else, don't hand back a result
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut run = true;
|
|
||||||
|
|
||||||
if maybe_jh.is_some() {
|
|
||||||
let mut jh = maybe_jh.unwrap();
|
|
||||||
|
|
||||||
// See if we finished, if so, return the value of the last execution
|
|
||||||
if let Poll::Ready(r) = poll!(&mut jh) {
|
|
||||||
out = Some(r);
|
|
||||||
// Task finished, unlock with a new task
|
|
||||||
} else {
|
|
||||||
// Still running, don't run again, unlock with the current join handle
|
|
||||||
run = false;
|
|
||||||
self.unlock(Some(jh));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run if we should do that
|
|
||||||
if run {
|
|
||||||
self.unlock(Some(spawn_local(future)));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Return the prior result if we have one
|
|
||||||
Ok((out, run))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cfg_if! {
|
|
||||||
if #[cfg(not(target_arch = "wasm32"))] {
|
|
||||||
impl<T> SingleFuture<T>
|
|
||||||
where
|
|
||||||
T: 'static + Send,
|
|
||||||
{
|
|
||||||
pub async fn single_spawn(
|
|
||||||
&self,
|
|
||||||
future: impl Future<Output = T> + Send + 'static,
|
|
||||||
) -> Result<(Option<T>, bool), ()> {
|
|
||||||
let mut out: Option<T> = None;
|
|
||||||
// See if we have a result we can return
|
|
||||||
let maybe_jh = match self.try_lock() {
|
|
||||||
Ok(v) => v,
|
|
||||||
Err(_) => {
|
|
||||||
// If we are already polling somewhere else, don't hand back a result
|
|
||||||
return Err(());
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let mut run = true;
|
|
||||||
if maybe_jh.is_some() {
|
|
||||||
let mut jh = maybe_jh.unwrap();
|
|
||||||
// See if we finished, if so, return the value of the last execution
|
|
||||||
if let Poll::Ready(r) = poll!(&mut jh) {
|
|
||||||
out = Some(r);
|
|
||||||
// Task finished, unlock with a new task
|
|
||||||
} else {
|
|
||||||
// Still running, don't run again, unlock with the current join handle
|
|
||||||
run = false;
|
|
||||||
self.unlock(Some(jh));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Run if we should do that
|
|
||||||
if run {
|
|
||||||
self.unlock(Some(spawn(future)));
|
|
||||||
}
|
|
||||||
// Return the prior result if we have one
|
|
||||||
Ok((out, run))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,5 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::intf::*;
|
use crate::*;
|
||||||
use core::sync::atomic::{AtomicU64, Ordering};
|
use core::sync::atomic::{AtomicU64, Ordering};
|
||||||
use once_cell::sync::OnceCell;
|
use once_cell::sync::OnceCell;
|
||||||
|
|
||||||
@ -90,7 +90,7 @@ impl TickTask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn tick(&self) -> Result<(), String> {
|
pub async fn tick(&self) -> Result<(), String> {
|
||||||
let now = get_timestamp();
|
let now = intf::get_timestamp();
|
||||||
let last_timestamp_us = self.last_timestamp_us.load(Ordering::Acquire);
|
let last_timestamp_us = self.last_timestamp_us.load(Ordering::Acquire);
|
||||||
|
|
||||||
if last_timestamp_us != 0u64 && (now - last_timestamp_us) < self.tick_period_us {
|
if last_timestamp_us != 0u64 && (now - last_timestamp_us) < self.tick_period_us {
|
||||||
|
@ -7,7 +7,6 @@ edition = "2021"
|
|||||||
crate-type = ["cdylib", "staticlib", "rlib"]
|
crate-type = ["cdylib", "staticlib", "rlib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
veilid-core = { path="../../veilid-core" }
|
|
||||||
tracing = { version = "^0", features = ["log", "attributes"] }
|
tracing = { version = "^0", features = ["log", "attributes"] }
|
||||||
tracing-subscriber = "^0"
|
tracing-subscriber = "^0"
|
||||||
parking_lot = "^0"
|
parking_lot = "^0"
|
||||||
@ -19,18 +18,20 @@ futures = "^0"
|
|||||||
# Dependencies for native builds only
|
# Dependencies for native builds only
|
||||||
# Linux, Windows, Mac, iOS, Android
|
# Linux, Windows, Mac, iOS, Android
|
||||||
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
[target.'cfg(not(target_arch = "wasm32"))'.dependencies]
|
||||||
async-std = { version = "^1", features = ["unstable"] }
|
veilid-core = { path="../../veilid-core", features = [ "rt-tokio" ] }
|
||||||
|
tokio = { version = "^1", features = ["full"] }
|
||||||
allo-isolate = "^0"
|
allo-isolate = "^0"
|
||||||
ffi-support = "^0"
|
ffi-support = "^0"
|
||||||
lazy_static = "^1"
|
lazy_static = "^1"
|
||||||
tracing-opentelemetry = "^0"
|
tracing-opentelemetry = "^0"
|
||||||
opentelemetry = { version = "^0", features = ["rt-async-std"] }
|
opentelemetry = { version = "^0", features = ["rt-tokio"] }
|
||||||
opentelemetry-otlp = { version = "^0", features = ["grpc-sys"] }
|
opentelemetry-otlp = { version = "^0" }
|
||||||
opentelemetry-semantic-conventions = "^0"
|
opentelemetry-semantic-conventions = "^0"
|
||||||
hostname = "^0"
|
hostname = "^0"
|
||||||
|
|
||||||
# Dependencies for WASM builds only
|
# Dependencies for WASM builds only
|
||||||
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
[target.'cfg(target_arch = "wasm32")'.dependencies]
|
||||||
|
veilid-core = { path="../../veilid-core" }
|
||||||
|
|
||||||
# Dependencies for Android builds only
|
# Dependencies for Android builds only
|
||||||
[target.'cfg(target_os = "android")'.dependencies]
|
[target.'cfg(target_os = "android")'.dependencies]
|
||||||
|
@ -11,8 +11,9 @@ name = "veilid-server"
|
|||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = [ "rt-async-std" ]
|
default = [ "rt-tokio" ]
|
||||||
rt-async-std = [ "veilid-core/rt-async-std", "async-std", "async-tungstenite/async-std-runtime", "opentelemetry/rt-async-std", "opentelemetry-otlp/grpc-sys"]
|
rt-async-std = [ "veilid-core/rt-async-std", "async-std", "opentelemetry/rt-async-std", "opentelemetry-otlp/grpc-sys"]
|
||||||
|
rt-tokio = [ "veilid-core/rt-tokio", "tokio", "opentelemetry/rt-tokio"]
|
||||||
tracking = ["veilid-core/tracking"]
|
tracking = ["veilid-core/tracking"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@ -26,6 +27,7 @@ opentelemetry-otlp = { version = "^0" }
|
|||||||
opentelemetry-semantic-conventions = "^0"
|
opentelemetry-semantic-conventions = "^0"
|
||||||
clap = "^3"
|
clap = "^3"
|
||||||
async-std = { version = "^1", features = ["unstable"], optional = true }
|
async-std = { version = "^1", features = ["unstable"], optional = true }
|
||||||
|
tokio = { version = "^1", features = ["full"], optional = true }
|
||||||
async-tungstenite = { version = "^0", features = ["async-tls"] }
|
async-tungstenite = { version = "^0", features = ["async-tls"] }
|
||||||
directories = "^4"
|
directories = "^4"
|
||||||
capnp = "^0"
|
capnp = "^0"
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
|
use crate::tools::*;
|
||||||
use crate::veilid_client_capnp::*;
|
use crate::veilid_client_capnp::*;
|
||||||
use async_std::net::TcpListener;
|
|
||||||
use async_std::prelude::FutureExt;
|
|
||||||
use capnp::capability::Promise;
|
use capnp::capability::Promise;
|
||||||
use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, RpcSystem};
|
use capnp_rpc::{pry, rpc_twoparty_capnp, twoparty, RpcSystem};
|
||||||
use failure::*;
|
use failure::*;
|
||||||
@ -232,7 +231,7 @@ impl veilid_server::Server for VeilidServerImpl {
|
|||||||
// --- Client API Server-Side ---------------------------------
|
// --- Client API Server-Side ---------------------------------
|
||||||
|
|
||||||
type ClientApiAllFuturesJoinHandle =
|
type ClientApiAllFuturesJoinHandle =
|
||||||
async_std::task::JoinHandle<Result<Vec<()>, Box<(dyn std::error::Error + 'static)>>>;
|
JoinHandle<Result<Vec<()>, Box<(dyn std::error::Error + 'static)>>>;
|
||||||
|
|
||||||
struct ClientApiInner {
|
struct ClientApiInner {
|
||||||
veilid_api: veilid_core::VeilidAPI,
|
veilid_api: veilid_core::VeilidAPI,
|
||||||
@ -286,13 +285,15 @@ impl ClientApi {
|
|||||||
let listener = TcpListener::bind(bind_addr).await?;
|
let listener = TcpListener::bind(bind_addr).await?;
|
||||||
debug!("Client API listening on: {:?}", bind_addr);
|
debug!("Client API listening on: {:?}", bind_addr);
|
||||||
|
|
||||||
// Get the
|
// Process the incoming accept stream
|
||||||
|
// xxx switch to stoptoken and use stream wrapper for tokio
|
||||||
let mut incoming = listener.incoming();
|
let mut incoming = listener.incoming();
|
||||||
let stop = self.inner.borrow().stop.clone();
|
let stop = self.inner.borrow().stop.clone();
|
||||||
let incoming_loop = async move {
|
let incoming_loop = async move {
|
||||||
while let Some(stream_result) = stop.instance_none().race(incoming.next()).await {
|
while let Some(stream_result) = stop.instance_none().race(incoming.next()).await {
|
||||||
let stream = stream_result?;
|
let stream = stream_result?;
|
||||||
stream.set_nodelay(true)?;
|
stream.set_nodelay(true)?;
|
||||||
|
// xxx use tokio split code too
|
||||||
let (reader, writer) = stream.split();
|
let (reader, writer) = stream.split();
|
||||||
let network = twoparty::VatNetwork::new(
|
let network = twoparty::VatNetwork::new(
|
||||||
reader,
|
reader,
|
||||||
@ -303,7 +304,7 @@ impl ClientApi {
|
|||||||
|
|
||||||
let rpc_system = RpcSystem::new(Box::new(network), Some(client.clone().client));
|
let rpc_system = RpcSystem::new(Box::new(network), Some(client.clone().client));
|
||||||
|
|
||||||
async_std::task::spawn_local(rpc_system.map(drop));
|
spawn_local(rpc_system.map(drop));
|
||||||
}
|
}
|
||||||
Ok::<(), Box<dyn std::error::Error>>(())
|
Ok::<(), Box<dyn std::error::Error>>(())
|
||||||
};
|
};
|
||||||
@ -332,7 +333,7 @@ impl ClientApi {
|
|||||||
|
|
||||||
if let Some(request_promise) = request(id, registration) {
|
if let Some(request_promise) = request(id, registration) {
|
||||||
let registration_map2 = registration_map1.clone();
|
let registration_map2 = registration_map1.clone();
|
||||||
async_std::task::spawn_local(request_promise.promise.map(move |r| match r {
|
spawn_local(request_promise.promise.map(move |r| match r {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
if let Some(ref mut s) =
|
if let Some(ref mut s) =
|
||||||
registration_map2.borrow_mut().registrations.get_mut(&id)
|
registration_map2.borrow_mut().registrations.get_mut(&id)
|
||||||
@ -385,6 +386,6 @@ impl ClientApi {
|
|||||||
.iter()
|
.iter()
|
||||||
.map(|addr| self.clone().handle_incoming(*addr, client.clone()));
|
.map(|addr| self.clone().handle_incoming(*addr, client.clone()));
|
||||||
let bind_futures_join = futures::future::try_join_all(bind_futures);
|
let bind_futures_join = futures::future::try_join_all(bind_futures);
|
||||||
self.inner.borrow_mut().join_handle = Some(async_std::task::spawn_local(bind_futures_join));
|
self.inner.borrow_mut().join_handle = Some(spawn_local(bind_futures_join));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,15 +6,16 @@ mod client_api;
|
|||||||
mod cmdline;
|
mod cmdline;
|
||||||
mod server;
|
mod server;
|
||||||
mod settings;
|
mod settings;
|
||||||
|
mod tools;
|
||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
mod unix;
|
mod unix;
|
||||||
mod veilid_logs;
|
mod veilid_logs;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
mod windows;
|
mod windows;
|
||||||
|
|
||||||
use async_std::task;
|
|
||||||
use cfg_if::*;
|
use cfg_if::*;
|
||||||
use server::*;
|
use server::*;
|
||||||
|
use tools::*;
|
||||||
use tracing::*;
|
use tracing::*;
|
||||||
use veilid_logs::*;
|
use veilid_logs::*;
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ fn main() -> Result<(), String> {
|
|||||||
// Handle non-normal server modes
|
// Handle non-normal server modes
|
||||||
if !matches!(server_mode, ServerMode::Normal) {
|
if !matches!(server_mode, ServerMode::Normal) {
|
||||||
// run the server to set the node id and quit
|
// run the server to set the node id and quit
|
||||||
return task::block_on(async {
|
return block_on(async {
|
||||||
// Init combined console/file logger
|
// Init combined console/file logger
|
||||||
let _logs = VeilidLogs::setup(settings.clone())?;
|
let _logs = VeilidLogs::setup(settings.clone())?;
|
||||||
|
|
||||||
@ -93,7 +94,7 @@ fn main() -> Result<(), String> {
|
|||||||
.expect("Error setting Ctrl-C handler");
|
.expect("Error setting Ctrl-C handler");
|
||||||
|
|
||||||
// Run the server loop
|
// Run the server loop
|
||||||
task::block_on(async {
|
block_on(async {
|
||||||
// Init combined console/file logger
|
// Init combined console/file logger
|
||||||
let _logs = VeilidLogs::setup(settings.clone())?;
|
let _logs = VeilidLogs::setup(settings.clone())?;
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
use crate::client_api;
|
use crate::client_api;
|
||||||
use crate::settings::*;
|
use crate::settings::*;
|
||||||
|
use crate::tools::*;
|
||||||
use flume::{unbounded, Receiver, Sender};
|
use flume::{unbounded, Receiver, Sender};
|
||||||
use lazy_static::*;
|
use lazy_static::*;
|
||||||
use parking_lot::Mutex;
|
use parking_lot::Mutex;
|
||||||
@ -77,7 +78,7 @@ pub async fn run_veilid_server_internal(
|
|||||||
|
|
||||||
// Process all updates
|
// Process all updates
|
||||||
let capi2 = capi.clone();
|
let capi2 = capi.clone();
|
||||||
let update_receiver_jh = async_std::task::spawn_local(async move {
|
let update_receiver_jh = spawn_local(async move {
|
||||||
while let Ok(change) = receiver.recv_async().await {
|
while let Ok(change) = receiver.recv_async().await {
|
||||||
if let Some(capi) = &capi2 {
|
if let Some(capi) = &capi2 {
|
||||||
// Handle state changes on main thread for capnproto rpc
|
// Handle state changes on main thread for capnproto rpc
|
||||||
@ -115,7 +116,7 @@ pub async fn run_veilid_server_internal(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
async_std::task::sleep(Duration::from_millis(100)).await;
|
sleep(Duration::from_millis(100)).await;
|
||||||
}
|
}
|
||||||
match veilid_api.debug("txtrecord".to_string()).await {
|
match veilid_api.debug("txtrecord".to_string()).await {
|
||||||
Ok(v) => {
|
Ok(v) => {
|
||||||
|
48
veilid-server/src/tools.rs
Normal file
48
veilid-server/src/tools.rs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
use cfg_if::*;
|
||||||
|
use core::future::Future;
|
||||||
|
|
||||||
|
cfg_if! {
|
||||||
|
if #[cfg(feature="rt-async-std")] {
|
||||||
|
pub use async_std::task::JoinHandle;
|
||||||
|
pub use async_std::net::TcpListener;
|
||||||
|
//pub use async_std::net::TcpStream;
|
||||||
|
//pub use async_std::future::TimeoutError;
|
||||||
|
pub fn spawn<F: Future<Output = T> + Send + 'static, T: Send + 'static>(f: F) -> JoinHandle<T> {
|
||||||
|
async_std::task::spawn_local(f)
|
||||||
|
}
|
||||||
|
pub fn spawn_local<F: Future<Output = T> + 'static, T: 'static>(f: F) -> JoinHandle<T> {
|
||||||
|
async_std::task::spawn_local(f)
|
||||||
|
}
|
||||||
|
pub fn spawn_detached_local<F: Future<Output = T> + 'static, T: 'static>(f: F) {
|
||||||
|
let _ = async_std::task::spawn_local(f);
|
||||||
|
}
|
||||||
|
pub use async_std::task::sleep;
|
||||||
|
pub use async_std::future::timeout;
|
||||||
|
pub fn block_on<F: Future<Output = T>, T>(f: F) -> T {
|
||||||
|
async_std::task::block_on(f)
|
||||||
|
}
|
||||||
|
} else if #[cfg(feature="rt-tokio")] {
|
||||||
|
pub use tokio::task::JoinHandle;
|
||||||
|
pub use tokio::net::TcpListener;
|
||||||
|
//pub use tokio::net::TcpStream;
|
||||||
|
//pub use tokio_util::compat::*;
|
||||||
|
pub use tokio::time::error::Elapsed as TimeoutError;
|
||||||
|
pub fn spawn<F: Future<Output = T> + Send + 'static, T: Send + 'static>(f: F) -> JoinHandle<T> {
|
||||||
|
tokio::task::spawn(f)
|
||||||
|
}
|
||||||
|
pub fn spawn_local<F: Future<Output = T> + 'static, T: 'static>(f: F) -> JoinHandle<T> {
|
||||||
|
tokio::task::spawn_local(f)
|
||||||
|
}
|
||||||
|
pub fn spawn_detached_local<F: Future<Output = T> + 'static, T: 'static>(f: F) {
|
||||||
|
let _ = tokio::task::spawn_local(f);
|
||||||
|
}
|
||||||
|
pub use tokio::time::sleep;
|
||||||
|
pub use tokio::time::timeout;
|
||||||
|
pub fn block_on<F: Future<Output = T>, T>(f: F) -> T {
|
||||||
|
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||||
|
let local = tokio::task::LocalSet::new();
|
||||||
|
local.block_on(&rt, f)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,9 @@
|
|||||||
use crate::server::*;
|
use crate::server::*;
|
||||||
use crate::settings::Settings;
|
use crate::settings::Settings;
|
||||||
|
use crate::tools::*;
|
||||||
use crate::veilid_logs::*;
|
use crate::veilid_logs::*;
|
||||||
use async_std::stream::StreamExt;
|
|
||||||
use async_std::task;
|
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
|
use futures::StreamExt;
|
||||||
use signal_hook::consts::signal::*;
|
use signal_hook::consts::signal::*;
|
||||||
use signal_hook_async_std::Signals;
|
use signal_hook_async_std::Signals;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
@ -96,7 +96,7 @@ pub fn run_daemon(settings: Settings, _matches: ArgMatches) -> Result<(), String
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Now, run the server
|
// Now, run the server
|
||||||
task::block_on(async {
|
block_on(async {
|
||||||
// Init combined console/file logger
|
// Init combined console/file logger
|
||||||
let _logs = VeilidLogs::setup(settings.clone())?;
|
let _logs = VeilidLogs::setup(settings.clone())?;
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ pub fn run_daemon(settings: Settings, _matches: ArgMatches) -> Result<(), String
|
|||||||
.map_err(|e| format!("failed to init signals: {}", e))?;
|
.map_err(|e| format!("failed to init signals: {}", e))?;
|
||||||
let handle = signals.handle();
|
let handle = signals.handle();
|
||||||
|
|
||||||
let signals_task = async_std::task::spawn(handle_signals(signals));
|
let signals_task = spawn(handle_signals(signals));
|
||||||
|
|
||||||
let res = run_veilid_server(settings, ServerMode::Normal).await;
|
let res = run_veilid_server(settings, ServerMode::Normal).await;
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
use crate::settings::*;
|
use crate::settings::*;
|
||||||
|
use crate::tools::*;
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
use log::*;
|
use log::*;
|
||||||
use std::ffi::OsString;
|
use std::ffi::OsString;
|
||||||
|
Loading…
Reference in New Issue
Block a user