Skip to content

Commit f8dce32

Browse files
committed
Start on 0.2.18
1 parent 2542317 commit f8dce32

File tree

20 files changed

+86
-42
lines changed

20 files changed

+86
-42
lines changed

.zed/settings.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// Folder-specific settings
2+
//
3+
// For a full list of overridable settings, and general information on folder-specific settings,
4+
// see the documentation: https://zed.dev/docs/configuring-zed#settings-files
5+
{
6+
"file_scan_exclusions": [
7+
".data",
8+
".git$",
9+
".hg",
10+
".rsync_cache",
11+
"assets/webpack",
12+
"build/static",
13+
"client/build",
14+
"CVS",
15+
"node_modules",
16+
"public/system/*",
17+
"tmp/cache",
18+
"**/.classpath",
19+
"**/.DS_Store",
20+
"**/.git",
21+
"**/.hg",
22+
"**/.settings",
23+
"**/.svn",
24+
"**/CVS",
25+
"**/Thumbs.db",
26+
".svn",
27+
"gems/scheduler/ext/*",
28+
"gems/server/ext/*",
29+
"benchmarks/results/*",
30+
"docs/static/*"
31+
]
32+
}

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## [0.2.18] - 2025-XX-XX
2+
### WIP
3+
-- Fixing error in auto-reload on Linux when reuse_port is false
4+
-- Fixing preload gem group logic
5+
-- Fix errors in interrupt handling during some debug flows
6+
17
## [0.2.17] - 2025-05-31
28
- Enabled vectorized writes in IoSteam
39
- Replaced all usage of heap-allocated BoxBody with HttpBody enums

Cargo.lock

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Gemfile.lock

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
PATH
22
remote: .
33
specs:
4-
itsi (0.2.17)
5-
itsi-scheduler (~> 0.2.17)
6-
itsi-server (~> 0.2.17)
4+
itsi (0.2.18)
5+
itsi-scheduler (~> 0.2.18)
6+
itsi-server (~> 0.2.18)
77

88
PATH
99
remote: gems/scheduler
1010
specs:
11-
itsi-scheduler (0.2.17)
11+
itsi-scheduler (0.2.18)
1212
rb_sys (~> 0.9.91)
1313

1414
PATH
1515
remote: gems/server
1616
specs:
17-
itsi-server (0.2.17)
17+
itsi-server (0.2.18)
1818
json (~> 2)
1919
prism (~> 1.4)
2020
rack (>= 1.6)

crates/itsi_scheduler/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "itsi-scheduler"
3-
version = "0.2.17"
3+
version = "0.2.18"
44
edition = "2021"
55
authors = ["Wouter Coppieters <[email protected]>"]
66
license = "MIT"

crates/itsi_server/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "itsi-server"
3-
version = "0.2.17"
3+
version = "0.2.18"
44
edition = "2021"
55
authors = ["Wouter Coppieters <[email protected]>"]
66
license = "MIT"

crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::{
1616
sync::mpsc,
1717
thread::{self},
1818
};
19-
use tracing::debug;
19+
use tracing::{debug, info};
2020

2121
/// Represents a set of patterns and commands.
2222
#[derive(Debug, Clone)]
@@ -96,7 +96,15 @@ pub fn watch_groups(pattern_groups: Vec<(String, Vec<Vec<String>>)>) -> Result<O
9696
let mut groups = Vec::new();
9797
for (pattern, commands) in pattern_groups.into_iter() {
9898
let base_dir = extract_and_canonicalize_base_dir(&pattern);
99-
let glob = Glob::new(pattern.trim_start_matches("./")).map_err(|e| {
99+
let cwd = PathBuf::from(".").canonicalize().unwrap();
100+
let relative_base_dir = base_dir.strip_prefix(&cwd).unwrap_or(&base_dir);
101+
info!(
102+
"Trimming pattern {:?} from {:?}",
103+
relative_base_dir, pattern
104+
);
105+
106+
let pattern = pattern.trim_start_matches(relative_base_dir.to_str().unwrap());
107+
let glob = Glob::new(pattern).map_err(|e| {
100108
magnus::Error::new(
101109
magnus::exception::standard_error(),
102110
format!("Failed to create watch glob: {}", e),
@@ -111,8 +119,8 @@ pub fn watch_groups(pattern_groups: Vec<(String, Vec<Vec<String>>)>) -> Result<O
111119
groups.push(PatternGroup {
112120
base_dir,
113121
glob_set,
114-
pattern,
115122
commands,
123+
pattern: pattern.to_string(),
116124
last_triggered: None,
117125
});
118126
}

crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ pub struct ServerParams {
8484
listener_info: Mutex<HashMap<String, i32>>,
8585
pub itsi_server_token_preference: ItsiServerTokenPreference,
8686
pub preloaded: AtomicBool,
87-
socket_opts: SocketOpts,
87+
pub socket_opts: SocketOpts,
8888
preexisting_listeners: Option<String>,
8989
}
9090

@@ -442,6 +442,10 @@ impl ItsiServerConfig {
442442
}
443443
}
444444

445+
pub fn use_reuse_port_load_balancing(&self) -> bool {
446+
cfg!(target_os = "linux") && self.server_params.read().socket_opts.reuse_port
447+
}
448+
445449
/// Reload
446450
pub fn reload(self: Arc<Self>, cluster_worker: bool) -> Result<bool> {
447451
let server_params = call_with_gvl(|ruby| {

crates/itsi_server/src/server/binds/listener.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -304,16 +304,16 @@ impl Listener {
304304
connect_tcp_socket(ip, port, &socket_opts).unwrap()
305305
}
306306

307-
pub fn into_tokio_listener(self, no_rebind: bool) -> TokioListener {
307+
pub fn into_tokio_listener(self, should_rebind: bool) -> TokioListener {
308308
match self {
309309
Listener::Tcp(mut listener) => {
310-
if cfg!(target_os = "linux") && !no_rebind {
310+
if should_rebind {
311311
listener = Listener::rebind_listener(listener);
312312
}
313313
TokioListener::Tcp(TokioTcpListener::from_std(listener).unwrap())
314314
}
315315
Listener::TcpTls((mut listener, acceptor)) => {
316-
if cfg!(target_os = "linux") && !no_rebind {
316+
if should_rebind {
317317
listener = Listener::rebind_listener(listener);
318318
}
319319
TokioListener::TcpTls(

crates/itsi_server/src/server/serve_strategy/cluster_mode.rs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -321,15 +321,6 @@ impl ClusterMode {
321321
.iter()
322322
.try_for_each(|worker| worker.boot(Arc::clone(&self)))?;
323323

324-
if cfg!(target_os = "linux") {
325-
self.server_config
326-
.server_params
327-
.write()
328-
.listeners
329-
.lock()
330-
.drain(..);
331-
};
332-
333324
let (sender, mut receiver) = watch::channel(());
334325
*CHILD_SIGNAL_SENDER.lock() = Some(sender);
335326

crates/itsi_server/src/server/serve_strategy/single_mode.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,14 @@ impl SingleMode {
262262
let shutdown_timeout = self.server_config.server_params.read().shutdown_timeout;
263263
let (shutdown_sender, _) = watch::channel(RunningPhase::Running);
264264
let monitor_thread = self.clone().start_monitors(thread_workers.clone());
265+
266+
// If we're on Linux with reuse_port enabled, we can use
267+
// kernel level load balancing across processes sharing a port.
268+
// To take advantage of this, these forks will rebind to the same port upon boot.
269+
// Worker 0 is special (this one just inherits the bind from the master process).
265270
let is_zero_worker = self.is_zero_worker();
271+
let should_rebind = !is_zero_worker || self.server_config.use_reuse_port_load_balancing();
272+
266273
if monitor_thread.is_none() {
267274
error!("Failed to start monitor thread");
268275
return Err(ItsiError::new("Failed to start monitor thread"));
@@ -283,7 +290,7 @@ impl SingleMode {
283290
.listeners
284291
.lock()
285292
.drain(..)
286-
.map(|list| Arc::new(list.into_tokio_listener(is_zero_worker)))
293+
.map(|list| Arc::new(list.into_tokio_listener(should_rebind)))
287294
.collect::<Vec<_>>();
288295

289296
tokio_listeners.iter().cloned().for_each(|listener| {

gems/scheduler/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gems/scheduler/lib/itsi/scheduler/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
module Itsi
44
class Scheduler
5-
VERSION = "0.2.17"
5+
VERSION = "0.2.18"
66
end
77
end

gems/server/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

gems/server/exe/itsi

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
require "itsi/server"
55
require "optparse"
66

7-
87
COMMANDS = {
98
"init" => "Initialize a new Itsi.rb server configuration file",
109
"status" => "Show the status of the server",
@@ -119,7 +118,6 @@ parser = OptionParser.new do |opts|
119118
options[:shutdown_timeout] = shutdown_timeout
120119
end
121120

122-
123121
opts.on("--stream-body", TrueClass, "Stream body frames (default: false for best compatibility)") do |stream_body|
124122
options[:stream_body] = stream_body
125123
end
@@ -159,7 +157,7 @@ parser = OptionParser.new do |opts|
159157
end
160158
end
161159

162-
if ENV['COMP_LINE'] || ARGV.include?('--completion')
160+
if ENV["COMP_LINE"] || ARGV.include?("--completion")
163161
puts COMMANDS.keys
164162
exit
165163
end
@@ -173,7 +171,7 @@ end
173171

174172
case (command = ARGV.shift)
175173
when *COMMANDS.keys
176-
required_arity = Itsi::Server.method(command).parameters&.select{|c| c.first == :req }&.length&.succ || 2
174+
required_arity = Itsi::Server.method(command).parameters&.select { |c| c.first == :req }&.length&.succ || 2
177175
case required_arity
178176
when 1 then Itsi::Server.send(command)
179177
when 2 then Itsi::Server.send(command, options)

gems/server/lib/itsi/server/config.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ def self.build_config(args, config_file_path, builder_proc = nil)
9797
errors << [e, e.backtrace[0]]
9898
end
9999
# If we're just preloading a specific gem group, we'll do that here too
100-
when Symbol
100+
when Symbol, String
101101
Itsi.log_debug("Preloading gem group #{preload}")
102102
Bundler.require(preload)
103103
end

gems/server/lib/itsi/server/config/options/reuse_port.rb

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,15 @@ module Itsi
22
class Server
33
module Config
44
class ReusePort < Option
5-
65
insert_text <<~SNIPPET
7-
reuse_port ${1|true,false|}
6+
reuse_port ${1|true,false|}
87
SNIPPET
98

109
detail "Configures whether the server should set the reuse_port option on the underlying socket."
1110

1211
schema do
13-
(Bool() & Required()).default(false)
12+
(Bool() & Required()).default(true)
1413
end
15-
1614
end
1715
end
1816
end

gems/server/lib/itsi/server/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22

33
module Itsi
44
class Server
5-
VERSION = "0.2.17"
5+
VERSION = "0.2.18"
66
end
77
end

itsi.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ Gem::Specification.new do |spec|
3333

3434
spec.require_paths = ['lib']
3535

36-
spec.add_dependency 'itsi-scheduler', '~> 0.2.17'
37-
spec.add_dependency 'itsi-server', '~> 0.2.17'
36+
spec.add_dependency 'itsi-scheduler', '~> 0.2.18'
37+
spec.add_dependency 'itsi-server', '~> 0.2.18'
3838
end

lib/itsi/version.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Itsi
2-
VERSION = '0.2.17'
2+
VERSION = '0.2.18'
33
end

0 commit comments

Comments
 (0)