Add dhat and rayon
- Set up dhat, when dhat-heap feature, the dhap memory profiler will run. Due to this tokio needs to be manually built. - Rayon now explicitly built outside of tokio runtime.
This commit is contained in:
parent
5075c97faa
commit
ade661d5b8
84
Cargo.lock
generated
84
Cargo.lock
generated
@ -287,6 +287,22 @@ dependencies = [
|
|||||||
"powerfmt",
|
"powerfmt",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dhat"
|
||||||
|
version = "0.3.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "98cd11d84628e233de0ce467de10b8633f4ddaecafadefc86e13b84b8739b827"
|
||||||
|
dependencies = [
|
||||||
|
"backtrace",
|
||||||
|
"lazy_static",
|
||||||
|
"mintex",
|
||||||
|
"parking_lot",
|
||||||
|
"rustc-hash",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thousands",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "digest"
|
name = "digest"
|
||||||
version = "0.10.7"
|
version = "0.10.7"
|
||||||
@ -785,6 +801,16 @@ version = "0.4.14"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lock_api"
|
||||||
|
version = "0.4.12"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
"scopeguard",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "log"
|
name = "log"
|
||||||
version = "0.4.22"
|
version = "0.4.22"
|
||||||
@ -829,6 +855,12 @@ dependencies = [
|
|||||||
"simd-adler32",
|
"simd-adler32",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mintex"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9bec4598fddb13cc7b528819e697852653252b760f1228b7642679bf2ff2cd07"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
@ -1011,6 +1043,29 @@ dependencies = [
|
|||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot"
|
||||||
|
version = "0.12.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27"
|
||||||
|
dependencies = [
|
||||||
|
"lock_api",
|
||||||
|
"parking_lot_core",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "parking_lot_core"
|
||||||
|
version = "0.9.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"redox_syscall",
|
||||||
|
"smallvec",
|
||||||
|
"windows-targets 0.52.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pem-rfc7468"
|
name = "pem-rfc7468"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -1129,6 +1184,7 @@ dependencies = [
|
|||||||
"base64",
|
"base64",
|
||||||
"bytes",
|
"bytes",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
|
"dhat",
|
||||||
"digest 0.11.0-pre.9",
|
"digest 0.11.0-pre.9",
|
||||||
"image",
|
"image",
|
||||||
"log",
|
"log",
|
||||||
@ -1143,6 +1199,7 @@ dependencies = [
|
|||||||
"pumpkin-text",
|
"pumpkin-text",
|
||||||
"pumpkin-world",
|
"pumpkin-world",
|
||||||
"rand",
|
"rand",
|
||||||
|
"rayon",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"rsa",
|
"rsa",
|
||||||
"rsa-der",
|
"rsa-der",
|
||||||
@ -1300,6 +1357,15 @@ dependencies = [
|
|||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "redox_syscall"
|
||||||
|
version = "0.5.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.6.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "reqwest"
|
name = "reqwest"
|
||||||
version = "0.12.5"
|
version = "0.12.5"
|
||||||
@ -1393,6 +1459,12 @@ version = "0.1.24"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustc-hash"
|
||||||
|
version = "1.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustix"
|
name = "rustix"
|
||||||
version = "0.38.34"
|
version = "0.38.34"
|
||||||
@ -1461,6 +1533,12 @@ dependencies = [
|
|||||||
"windows-sys 0.52.0",
|
"windows-sys 0.52.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "scopeguard"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "2.11.1"
|
version = "2.11.1"
|
||||||
@ -1721,6 +1799,12 @@ dependencies = [
|
|||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "thousands"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3bf63baf9f5039dadc247375c29eb13706706cfde997d0330d05aa63a77d8820"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "time"
|
name = "time"
|
||||||
version = "0.3.36"
|
version = "0.3.36"
|
||||||
|
|||||||
@ -7,9 +7,10 @@ version = "0.1.0"
|
|||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
strip = true
|
debug = 1
|
||||||
lto = true
|
lto = true
|
||||||
codegen-units = 1
|
codegen-units = 1
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
tokio = { version = "1.39.2", features = ["net", "macros", "rt-multi-thread", "fs", "io-util"] }
|
tokio = { version = "1.39.2", features = ["net", "macros", "rt-multi-thread", "fs", "io-util"] }
|
||||||
|
rayon = "1.10.0"
|
||||||
|
|||||||
@ -4,7 +4,15 @@ version = "0.1.0-dev"
|
|||||||
description = "Empowering everyone to host fast and efficient Minecraft servers."
|
description = "Empowering everyone to host fast and efficient Minecraft servers."
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = []
|
||||||
|
dhat-heap = ["dhat"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
# memory analysis
|
||||||
|
dhat = { version = "0.3.3", optional = true }
|
||||||
|
|
||||||
|
# pumpkin
|
||||||
pumpkin-text = { path = "../pumpkin-text" }
|
pumpkin-text = { path = "../pumpkin-text" }
|
||||||
pumpkin-inventory = { path = "../pumpkin-inventory"}
|
pumpkin-inventory = { path = "../pumpkin-inventory"}
|
||||||
pumpkin-world = { path = "../pumpkin-world"}
|
pumpkin-world = { path = "../pumpkin-world"}
|
||||||
@ -51,4 +59,5 @@ crossbeam-channel = "0.5.13"
|
|||||||
|
|
||||||
uuid = { version = "1.10", features = ["serde", "v3"]}
|
uuid = { version = "1.10", features = ["serde", "v3"]}
|
||||||
|
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
rayon.workspace = true
|
||||||
|
|||||||
@ -22,141 +22,156 @@ pub mod rcon;
|
|||||||
pub mod server;
|
pub mod server;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
|
#[cfg(feature = "dhat-heap")]
|
||||||
|
#[global_allocator]
|
||||||
|
static ALLOC: dhat::Alloc = dhat::Alloc;
|
||||||
|
|
||||||
#[cfg(not(target_os = "wasi"))]
|
#[cfg(not(target_os = "wasi"))]
|
||||||
#[tokio::main]
|
fn main() -> io::Result<()> {
|
||||||
async fn main() -> io::Result<()> {
|
#[cfg(feature = "dhat-heap")]
|
||||||
const SERVER: Token = Token(0);
|
let _profiler = dhat::Profiler::new_heap();
|
||||||
use std::{cell::RefCell, time::Instant};
|
#[cfg(feature = "dhat-heap")]
|
||||||
|
println!("Using a memory profiler");
|
||||||
|
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
// ensure rayon is built outside of tokio scope
|
||||||
|
rayon::ThreadPoolBuilder::new().build_global().unwrap();
|
||||||
|
rt.block_on(async {
|
||||||
|
const SERVER: Token = Token(0);
|
||||||
|
use std::{cell::RefCell, time::Instant};
|
||||||
|
|
||||||
use rcon::RCONServer;
|
use rcon::RCONServer;
|
||||||
|
|
||||||
let time = Instant::now();
|
let time = Instant::now();
|
||||||
let basic_config = BasicConfiguration::load("configuration.toml");
|
let basic_config = BasicConfiguration::load("configuration.toml");
|
||||||
|
|
||||||
let advanced_configuration = AdvancedConfiguration::load("features.toml");
|
let advanced_configuration = AdvancedConfiguration::load("features.toml");
|
||||||
|
|
||||||
simple_logger::SimpleLogger::new().init().unwrap();
|
simple_logger::SimpleLogger::new().init().unwrap();
|
||||||
|
|
||||||
// Create a poll instance.
|
// Create a poll instance.
|
||||||
let mut poll = Poll::new()?;
|
let mut poll = Poll::new()?;
|
||||||
// Create storage for events.
|
// Create storage for events.
|
||||||
let mut events = Events::with_capacity(128);
|
let mut events = Events::with_capacity(128);
|
||||||
|
|
||||||
// Setup the TCP server socket.
|
// Setup the TCP server socket.
|
||||||
|
|
||||||
let addr = format!(
|
let addr = format!(
|
||||||
"{}:{}",
|
"{}:{}",
|
||||||
basic_config.server_address, basic_config.server_port
|
basic_config.server_address, basic_config.server_port
|
||||||
)
|
)
|
||||||
.parse()
|
.parse()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut listener = TcpListener::bind(addr)?;
|
let mut listener = TcpListener::bind(addr)?;
|
||||||
|
|
||||||
// Register the server with poll we can receive events for it.
|
// Register the server with poll we can receive events for it.
|
||||||
poll.registry()
|
poll.registry()
|
||||||
.register(&mut listener, SERVER, Interest::READABLE)?;
|
.register(&mut listener, SERVER, Interest::READABLE)?;
|
||||||
|
|
||||||
// Unique token for each incoming connection.
|
// Unique token for each incoming connection.
|
||||||
let mut unique_token = Token(SERVER.0 + 1);
|
let mut unique_token = Token(SERVER.0 + 1);
|
||||||
|
|
||||||
let use_console = advanced_configuration.commands.use_console;
|
let use_console = advanced_configuration.commands.use_console;
|
||||||
let rcon = advanced_configuration.rcon.clone();
|
let rcon = advanced_configuration.rcon.clone();
|
||||||
|
|
||||||
let mut connections: HashMap<Token, Rc<RefCell<Client>>> = HashMap::new();
|
let mut connections: HashMap<Token, Rc<RefCell<Client>>> = HashMap::new();
|
||||||
|
|
||||||
let mut server = Server::new((basic_config, advanced_configuration));
|
let mut server = Server::new((basic_config, advanced_configuration));
|
||||||
log::info!("Started Server took {}ms", time.elapsed().as_millis());
|
log::info!("Started Server took {}ms", time.elapsed().as_millis());
|
||||||
log::info!("You now can connect to the server");
|
log::info!("You now can connect to the server");
|
||||||
|
|
||||||
if use_console {
|
if use_console {
|
||||||
thread::spawn(move || {
|
thread::spawn(move || {
|
||||||
let stdin = std::io::stdin();
|
let stdin = std::io::stdin();
|
||||||
loop {
|
loop {
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
stdin
|
stdin
|
||||||
.read_line(&mut out)
|
.read_line(&mut out)
|
||||||
.expect("Failed to read console line");
|
.expect("Failed to read console line");
|
||||||
handle_command(&mut commands::CommandSender::Console, &out);
|
handle_command(&mut commands::CommandSender::Console, &out);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
if rcon.enabled {
|
|
||||||
tokio::spawn(async move {
|
|
||||||
RCONServer::new(&rcon).await.unwrap();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
loop {
|
|
||||||
if let Err(err) = poll.poll(&mut events, None) {
|
|
||||||
if interrupted(&err) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
return Err(err);
|
|
||||||
}
|
}
|
||||||
|
if rcon.enabled {
|
||||||
|
tokio::spawn(async move {
|
||||||
|
RCONServer::new(&rcon).await.unwrap();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
loop {
|
||||||
|
if let Err(err) = poll.poll(&mut events, None) {
|
||||||
|
if interrupted(&err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return Err(err);
|
||||||
|
}
|
||||||
|
|
||||||
for event in events.iter() {
|
for event in events.iter() {
|
||||||
match event.token() {
|
match event.token() {
|
||||||
SERVER => loop {
|
SERVER => loop {
|
||||||
// Received an event for the TCP server socket, which
|
// Received an event for the TCP server socket, which
|
||||||
// indicates we can accept an connection.
|
// indicates we can accept an connection.
|
||||||
let (mut connection, address) = match listener.accept() {
|
let (mut connection, address) = match listener.accept() {
|
||||||
Ok((connection, address)) => (connection, address),
|
Ok((connection, address)) => (connection, address),
|
||||||
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
|
Err(e) if e.kind() == io::ErrorKind::WouldBlock => {
|
||||||
// If we get a `WouldBlock` error we know our
|
// If we get a `WouldBlock` error we know our
|
||||||
// listener has no more incoming connections queued,
|
// listener has no more incoming connections queued,
|
||||||
// so we can return to polling and wait for some
|
// so we can return to polling and wait for some
|
||||||
// more.
|
// more.
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
// If it was any other kind of error, something went
|
||||||
|
// wrong and we terminate with an error.
|
||||||
|
return Err(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if let Err(e) = connection.set_nodelay(true) {
|
||||||
|
log::warn!("failed to set TCP_NODELAY {e}");
|
||||||
}
|
}
|
||||||
Err(e) => {
|
|
||||||
// If it was any other kind of error, something went
|
|
||||||
// wrong and we terminate with an error.
|
|
||||||
return Err(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if let Err(e) = connection.set_nodelay(true) {
|
|
||||||
log::warn!("failed to set TCP_NODELAY {e}");
|
|
||||||
}
|
|
||||||
|
|
||||||
log::info!("Accepted connection from: {}", address);
|
log::info!("Accepted connection from: {}", address);
|
||||||
|
|
||||||
let token = next(&mut unique_token);
|
let token = next(&mut unique_token);
|
||||||
poll.registry().register(
|
poll.registry().register(
|
||||||
&mut connection,
|
&mut connection,
|
||||||
token,
|
token,
|
||||||
Interest::READABLE.add(Interest::WRITABLE),
|
Interest::READABLE.add(Interest::WRITABLE),
|
||||||
)?;
|
)?;
|
||||||
let rc_token = Rc::new(token);
|
let rc_token = Rc::new(token);
|
||||||
let client = Rc::new(RefCell::new(Client::new(
|
let client = Rc::new(RefCell::new(Client::new(
|
||||||
Rc::clone(&rc_token),
|
Rc::clone(&rc_token),
|
||||||
connection,
|
connection,
|
||||||
addr,
|
addr,
|
||||||
)));
|
)));
|
||||||
server.add_client(rc_token, Rc::clone(&client));
|
server.add_client(rc_token, Rc::clone(&client));
|
||||||
connections.insert(token, client);
|
connections.insert(token, client);
|
||||||
},
|
},
|
||||||
|
|
||||||
token => {
|
token => {
|
||||||
// Maybe received an event for a TCP connection.
|
// Maybe received an event for a TCP connection.
|
||||||
let done = if let Some(client) = connections.get_mut(&token) {
|
let done = if let Some(client) = connections.get_mut(&token) {
|
||||||
let mut client = client.borrow_mut();
|
|
||||||
client.poll(&mut server, event).await;
|
|
||||||
client.closed
|
|
||||||
} else {
|
|
||||||
// Sporadic events happen, we can safely ignore them.
|
|
||||||
false
|
|
||||||
};
|
|
||||||
if done {
|
|
||||||
if let Some(client) = connections.remove(&token) {
|
|
||||||
server.remove_client(&token);
|
|
||||||
let mut client = client.borrow_mut();
|
let mut client = client.borrow_mut();
|
||||||
poll.registry().deregister(&mut client.connection)?;
|
client.poll(&mut server, event).await;
|
||||||
|
client.closed
|
||||||
|
} else {
|
||||||
|
// Sporadic events happen, we can safely ignore them.
|
||||||
|
false
|
||||||
|
};
|
||||||
|
if done {
|
||||||
|
if let Some(client) = connections.remove(&token) {
|
||||||
|
server.remove_client(&token);
|
||||||
|
let mut client = client.borrow_mut();
|
||||||
|
poll.registry().deregister(&mut client.connection)?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next(current: &mut Token) -> Token {
|
fn next(current: &mut Token) -> Token {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user