itsi 0.2.18 → 0.2.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d643690ccc0157ece254b12b72bd4eff904a907db970639df8567c43693b2c7b
4
- data.tar.gz: 5202c977ca30f83ddc09fc9bbe31966b06ffb5beda308568a684e0242d3898f7
3
+ metadata.gz: 8707abd045843bf5567c62f0f458db47d582d5e711916627d93b7c8b68bec8f6
4
+ data.tar.gz: a0d55d6f5048ffc3f5d779ab3fe46ffa89f6994af18fbaf1dad908f51b80ff74
5
5
  SHA512:
6
- metadata.gz: 07567a207915ae2f6d4dc0c6827e5b9008574f1e8b9864b0969657a06d5f96f4d638b0532187da82511b7f71b06c7bc1499fd1cd32cb7e85fa13c3cb0d76e34a
7
- data.tar.gz: 0f7bfcc95d1a79deae127f6899122c8ffd3d3042332ad33bbc2cf0e490abb9392dfbce76f4cbcfa878b58ef8e6ee8b3694853994c9c78dbc2b4165fe76bf6be5
6
+ metadata.gz: d649294f7eae29ea5dee877f52a6f6e255cd3b4c7eca008e8ff8670d996b206ae9dedf04fdba3c80540b9fbee1b072df2f60e03d363b4868b2cac8e69679a798
7
+ data.tar.gz: 233febdc6634ee20ff69228dcf8a0c7c42633461d98da67cb7391e2d3beef5e736e8843034a56cbe897d8a9f51993371c9d8c234cb3e9fddd27f7f11455b0b69
data/CHANGELOG.md CHANGED
@@ -1,10 +1,14 @@
1
- ## [0.2.18] - 2025-XX-XX
2
- ### WIP
3
- -- Fixing error in auto-reload on Linux when reuse_port is false
4
- -- Fix breaking of auto-reload on config file errors
5
- -- include directive is relative (equivalent to require_relative)
6
- -- Fixing preload gem group logic
7
- -- Fix errors in interrupt handling during some debug flows
1
+ ## [0.2.19] - 2025-08-09
2
+ - Fixed shutdown hook incorrectly being skipped
3
+ - Documentation fixes
4
+ - Fixed stuck graceful shutdown scenario
5
+
6
+ ## [0.2.18] - 2025-06-20
7
+ - Fixing error in auto-reload on Linux when reuse_port is false
8
+ - Fix breaking of auto-reload on config file errors
9
+ - include directive is relative (equivalent to require_relative)
10
+ - Fixing preload gem group logic
11
+ - Fix errors in interrupt handling during some debug flows
8
12
 
9
13
  ## [0.2.17] - 2025-05-31
10
14
  - Enabled vectorized writes in IoSteam
data/Cargo.lock CHANGED
@@ -1644,7 +1644,7 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
1644
1644
 
1645
1645
  [[package]]
1646
1646
  name = "itsi-scheduler"
1647
- version = "0.2.18"
1647
+ version = "0.2.19"
1648
1648
  dependencies = [
1649
1649
  "bytes",
1650
1650
  "derive_more",
@@ -1662,7 +1662,7 @@ dependencies = [
1662
1662
 
1663
1663
  [[package]]
1664
1664
  name = "itsi-server"
1665
- version = "0.2.18"
1665
+ version = "0.2.19"
1666
1666
  dependencies = [
1667
1667
  "argon2",
1668
1668
  "async-channel",
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "itsi-scheduler"
3
- version = "0.2.18"
3
+ version = "0.2.19"
4
4
  edition = "2021"
5
5
  authors = ["Wouter Coppieters <wc@pico.net.nz>"]
6
6
  license = "MIT"
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "mkmf"
4
- require "rb_sys/mkmf"
3
+ require 'mkmf'
4
+ require 'rb_sys/mkmf'
5
5
 
6
- create_rust_makefile("itsi/scheduler/itsi_scheduler") do |r|
7
- r.extra_rustflags = ["-C target-cpu=native"]
6
+ create_rust_makefile('itsi/scheduler/itsi_scheduler') do |r|
7
+ r.extra_rustflags = ['-C target-cpu=native']
8
+ r.env = {
9
+ 'BINDGEN_EXTRA_CLANG_ARGS' => '-include stdbool.h -std=c99'
10
+ }
8
11
  end
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "itsi-server"
3
- version = "0.2.18"
3
+ version = "0.2.19"
4
4
  edition = "2021"
5
5
  authors = ["Wouter Coppieters <wc@pico.net.nz>"]
6
6
  license = "MIT"
@@ -1,8 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "mkmf"
4
- require "rb_sys/mkmf"
3
+ require 'mkmf'
4
+ require 'rb_sys/mkmf'
5
5
 
6
- create_rust_makefile("itsi/server/itsi_server") do |r|
7
- r.extra_rustflags = ["-C target-cpu=native"]
6
+ create_rust_makefile('itsi/server/itsi_server') do |r|
7
+ r.extra_rustflags = ['-C target-cpu=native']
8
+ r.env = {
9
+ 'BINDGEN_EXTRA_CLANG_ARGS' => '-include stdbool.h -std=c99'
10
+ }
8
11
  end
@@ -377,9 +377,13 @@ impl ClusterMode {
377
377
  }
378
378
  lifecycle_event = lifecycle_rx.recv() => match lifecycle_event{
379
379
  Ok(lifecycle_event) => {
380
+ debug!("Cluster mode received lifecycle event: {:?}", lifecycle_event);
380
381
  if let Err(e) = self_ref.clone().handle_lifecycle_event(lifecycle_event).await{
381
382
  match e {
382
- ItsiError::Break => break,
383
+ ItsiError::Break => {
384
+ debug!("Lifecycle event triggered shutdown, breaking cluster monitor loop");
385
+ break;
386
+ },
383
387
  _ => error!("Error in handle_lifecycle_event {:?}", e)
384
388
  }
385
389
  }
@@ -1,11 +1,12 @@
1
1
  use std::{
2
2
  collections::VecDeque,
3
- sync::atomic::{AtomicBool, AtomicI8},
3
+ sync::atomic::{AtomicBool, AtomicI8, Ordering},
4
4
  };
5
5
 
6
6
  use nix::libc::{self, sighandler_t};
7
7
  use parking_lot::Mutex;
8
8
  use tokio::sync::broadcast;
9
+ use tracing::{debug, warn};
9
10
 
10
11
  use super::lifecycle_event::LifecycleEvent;
11
12
 
@@ -21,12 +22,14 @@ pub fn subscribe_runtime_to_signals() -> broadcast::Receiver<LifecycleEvent> {
21
22
  if let Some(sender) = guard.as_ref() {
22
23
  return sender.subscribe();
23
24
  }
24
- let (sender, receiver) = broadcast::channel(5);
25
+ let (sender, receiver) = broadcast::channel(32);
25
26
  let sender_clone = sender.clone();
26
27
  std::thread::spawn(move || {
27
- std::thread::sleep(std::time::Duration::from_millis(50));
28
+ std::thread::sleep(std::time::Duration::from_millis(10));
28
29
  for event in PENDING_QUEUE.lock().drain(..) {
29
- sender_clone.send(event).ok();
30
+ if let Err(e) = sender_clone.send(event) {
31
+ eprintln!("Warning: Failed to send pending lifecycle event {:?}", e);
32
+ }
30
33
  }
31
34
  });
32
35
 
@@ -41,22 +44,36 @@ pub fn unsubscribe_runtime() {
41
44
 
42
45
  pub fn send_lifecycle_event(event: LifecycleEvent) {
43
46
  if let Some(sender) = SIGNAL_HANDLER_CHANNEL.lock().as_ref() {
44
- sender.send(event).ok();
47
+ if let Err(e) = sender.send(event) {
48
+ // Channel full or receivers dropped - this is a critical error for shutdown signals
49
+ eprintln!("Critical: Failed to send lifecycle event {:?}", e);
50
+ // For shutdown events, try to force exit if channel delivery fails
51
+ if matches!(
52
+ e.0,
53
+ LifecycleEvent::Shutdown | LifecycleEvent::ForceShutdown
54
+ ) {
55
+ eprintln!("Emergency shutdown due to signal delivery failure");
56
+ std::process::exit(1);
57
+ }
58
+ }
45
59
  } else {
46
60
  PENDING_QUEUE.lock().push_back(event);
47
61
  }
48
62
  }
49
63
 
50
64
  fn receive_signal(signum: i32, _: sighandler_t) {
51
- SIGINT_COUNT.fetch_add(-1, std::sync::atomic::Ordering::SeqCst);
65
+ debug!("Received signal: {}", signum);
66
+ SIGINT_COUNT.fetch_add(-1, Ordering::SeqCst);
52
67
  let event = match signum {
53
68
  libc::SIGTERM | libc::SIGINT => {
54
- SHUTDOWN_REQUESTED.store(true, std::sync::atomic::Ordering::SeqCst);
55
- SIGINT_COUNT.fetch_add(2, std::sync::atomic::Ordering::SeqCst);
56
- if SIGINT_COUNT.load(std::sync::atomic::Ordering::SeqCst) < 2 {
69
+ debug!("Received shutdown signal (SIGTERM/SIGINT)");
70
+ SHUTDOWN_REQUESTED.store(true, Ordering::SeqCst);
71
+ SIGINT_COUNT.fetch_add(2, Ordering::SeqCst);
72
+ if SIGINT_COUNT.load(Ordering::SeqCst) < 2 {
73
+ debug!("First shutdown signal, requesting graceful shutdown");
57
74
  Some(LifecycleEvent::Shutdown)
58
75
  } else {
59
- // Not messing about. Force shutdown.
76
+ warn!("Multiple shutdown signals received, forcing immediate shutdown");
60
77
  Some(LifecycleEvent::ForceShutdown)
61
78
  }
62
79
  }
@@ -70,13 +87,17 @@ fn receive_signal(signum: i32, _: sighandler_t) {
70
87
  };
71
88
 
72
89
  if let Some(event) = event {
90
+ debug!("Signal {} mapped to lifecycle event: {:?}", signum, event);
73
91
  send_lifecycle_event(event);
92
+ } else {
93
+ debug!("Signal {} not mapped to any lifecycle event", signum);
74
94
  }
75
95
  }
76
96
 
77
97
  pub fn reset_signal_handlers() -> bool {
78
- SIGINT_COUNT.store(0, std::sync::atomic::Ordering::SeqCst);
79
- SHUTDOWN_REQUESTED.store(false, std::sync::atomic::Ordering::SeqCst);
98
+ debug!("Resetting signal handlers");
99
+ SIGINT_COUNT.store(0, Ordering::SeqCst);
100
+ SHUTDOWN_REQUESTED.store(false, Ordering::SeqCst);
80
101
 
81
102
  unsafe {
82
103
  libc::signal(libc::SIGTERM, receive_signal as usize);
@@ -92,6 +113,7 @@ pub fn reset_signal_handlers() -> bool {
92
113
  }
93
114
 
94
115
  pub fn clear_signal_handlers() {
116
+ debug!("Clearing signal handlers");
95
117
  unsafe {
96
118
  libc::signal(libc::SIGTERM, libc::SIG_DFL);
97
119
  libc::signal(libc::SIGINT, libc::SIG_DFL);
@@ -2,7 +2,7 @@
2
2
  Simple example of how you can use the following options:
3
3
 
4
4
  * https://itsi.fyi/middleware/endpoint/
5
- * https://itsi.fyi/middleware/endpoint/controller
5
+ * https://itsi.fyi/middleware/controller
6
6
  * https://itsi.fyi/middleware/endpoint/schemas/
7
7
 
8
8
  to create validated JSON endpoints directly inside Itsi without a dedicated framework
@@ -213,7 +213,7 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
213
213
 
214
214
  [[package]]
215
215
  name = "itsi-scheduler"
216
- version = "0.2.18"
216
+ version = "0.2.19"
217
217
  dependencies = [
218
218
  "bytes",
219
219
  "derive_more",
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Itsi
4
4
  class Scheduler
5
- VERSION = "0.2.18"
5
+ VERSION = "0.2.19"
6
6
  end
7
7
  end
@@ -1644,7 +1644,7 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
1644
1644
 
1645
1645
  [[package]]
1646
1646
  name = "itsi-server"
1647
- version = "0.2.18"
1647
+ version = "0.2.19"
1648
1648
  dependencies = [
1649
1649
  "argon2",
1650
1650
  "async-channel",
@@ -39,7 +39,7 @@ How to identify the client:
39
39
  ```
40
40
  or
41
41
  ```ruby
42
- key: { parameter: { query: { name: "user_id" } } }
42
+ key: { parameter: { query: "user_id" } }
43
43
  ```
44
44
 
45
45
  ### `store_config`
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Itsi
4
4
  class Server
5
- VERSION = "0.2.18"
5
+ VERSION = "0.2.19"
6
6
  end
7
7
  end
data/lib/itsi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Itsi
2
- VERSION = '0.2.18'
2
+ VERSION = '0.2.19'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: itsi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.18
4
+ version: 0.2.19
5
5
  platform: ruby
6
6
  authors:
7
7
  - Wouter Coppieters
@@ -15,28 +15,28 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 0.2.18
18
+ version: 0.2.19
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 0.2.18
25
+ version: 0.2.19
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: itsi-server
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
30
30
  - - "~>"
31
31
  - !ruby/object:Gem::Version
32
- version: 0.2.18
32
+ version: 0.2.19
33
33
  type: :runtime
34
34
  prerelease: false
35
35
  version_requirements: !ruby/object:Gem::Requirement
36
36
  requirements:
37
37
  - - "~>"
38
38
  - !ruby/object:Gem::Version
39
- version: 0.2.18
39
+ version: 0.2.19
40
40
  description: Wrapper Gem for both the Itsi server and the Itsi Fiber scheduler
41
41
  email:
42
42
  - wc@pico.net.nz