itsi 0.1.7 → 0.1.9

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.
Files changed (249) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +21 -0
  3. data/crates/itsi_error/src/from.rs +26 -29
  4. data/crates/itsi_server/Cargo.lock +2956 -0
  5. data/crates/itsi_server/Cargo.toml +1 -1
  6. data/crates/itsi_server/src/lib.rs +5 -0
  7. data/crates/itsi_server/src/request/itsi_request.rs +37 -9
  8. data/crates/itsi_server/src/response/itsi_response.rs +12 -2
  9. data/crates/itsi_server/src/server/bind.rs +4 -3
  10. data/crates/itsi_server/src/server/itsi_server.rs +128 -78
  11. data/crates/itsi_server/src/server/listener.rs +98 -107
  12. data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +40 -24
  13. data/crates/itsi_server/src/server/signal.rs +7 -0
  14. data/crates/itsi_server/src/server/thread_worker.rs +3 -4
  15. data/crates/itsi_server/src/server/tls.rs +20 -13
  16. data/crates/itsi_tracing/src/lib.rs +18 -1
  17. data/gems/scheduler/Cargo.lock +12 -12
  18. data/gems/scheduler/ext/itsi_error/src/from.rs +26 -29
  19. data/gems/scheduler/ext/itsi_server/Cargo.lock +2956 -0
  20. data/gems/scheduler/ext/itsi_server/Cargo.toml +1 -1
  21. data/gems/scheduler/ext/itsi_server/src/lib.rs +5 -0
  22. data/gems/scheduler/ext/itsi_server/src/request/itsi_request.rs +37 -9
  23. data/gems/scheduler/ext/itsi_server/src/response/itsi_response.rs +12 -2
  24. data/gems/scheduler/ext/itsi_server/src/server/bind.rs +4 -3
  25. data/gems/scheduler/ext/itsi_server/src/server/itsi_server.rs +128 -78
  26. data/gems/scheduler/ext/itsi_server/src/server/listener.rs +98 -107
  27. data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/single_mode.rs +40 -24
  28. data/gems/scheduler/ext/itsi_server/src/server/signal.rs +7 -0
  29. data/gems/scheduler/ext/itsi_server/src/server/thread_worker.rs +3 -4
  30. data/gems/scheduler/ext/itsi_server/src/server/tls.rs +20 -13
  31. data/gems/scheduler/ext/itsi_tracing/src/lib.rs +18 -1
  32. data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
  33. data/gems/scheduler/test/test_address_resolve.rb +0 -1
  34. data/gems/scheduler/test/test_file_io.rb +0 -1
  35. data/gems/scheduler/test/test_kernel_sleep.rb +3 -4
  36. data/gems/server/Cargo.lock +2917 -0
  37. data/gems/server/Cargo.toml +7 -0
  38. data/gems/server/Rakefile +8 -1
  39. data/gems/server/ext/itsi_error/src/from.rs +26 -29
  40. data/gems/server/ext/itsi_server/Cargo.lock +2956 -0
  41. data/gems/server/ext/itsi_server/Cargo.toml +1 -1
  42. data/gems/server/ext/itsi_server/src/lib.rs +5 -0
  43. data/gems/server/ext/itsi_server/src/request/itsi_request.rs +37 -9
  44. data/gems/server/ext/itsi_server/src/response/itsi_response.rs +12 -2
  45. data/gems/server/ext/itsi_server/src/server/bind.rs +4 -3
  46. data/gems/server/ext/itsi_server/src/server/itsi_server.rs +128 -78
  47. data/gems/server/ext/itsi_server/src/server/listener.rs +98 -107
  48. data/gems/server/ext/itsi_server/src/server/serve_strategy/single_mode.rs +40 -24
  49. data/gems/server/ext/itsi_server/src/server/signal.rs +7 -0
  50. data/gems/server/ext/itsi_server/src/server/thread_worker.rs +3 -4
  51. data/gems/server/ext/itsi_server/src/server/tls.rs +20 -13
  52. data/gems/server/ext/itsi_tracing/src/lib.rs +18 -1
  53. data/gems/server/lib/itsi/index.html +91 -0
  54. data/gems/server/lib/itsi/request.rb +29 -21
  55. data/gems/server/lib/itsi/server/rack/handler/itsi.rb +3 -4
  56. data/gems/server/lib/itsi/server/rack_interface.rb +79 -0
  57. data/gems/server/lib/itsi/server/scheduler_interface.rb +21 -0
  58. data/gems/server/lib/itsi/server/scheduler_mode.rb +1 -1
  59. data/gems/server/lib/itsi/server/signal_trap.rb +24 -0
  60. data/gems/server/lib/itsi/server/version.rb +1 -1
  61. data/gems/server/lib/itsi/server.rb +68 -82
  62. data/gems/server/test/helpers/test_helper.rb +28 -0
  63. data/gems/server/test/test_itsi_server.rb +275 -3
  64. data/lib/itsi/version.rb +1 -1
  65. data/sandbox/deploy/main.tf +238 -0
  66. data/sandbox/deploy/outputs.tf +4 -0
  67. data/sandbox/deploy/vars.tf +11 -0
  68. data/sandbox/falcon_benchmark/Gemfile +10 -0
  69. data/sandbox/falcon_benchmark/Gemfile.lock +140 -0
  70. data/sandbox/falcon_benchmark/config.ru +54 -0
  71. data/sandbox/itsi_sandbox_async/Gemfile +10 -0
  72. data/sandbox/itsi_sandbox_async/Gemfile.lock +69 -0
  73. data/sandbox/itsi_sandbox_async/config.ru +10 -0
  74. data/sandbox/itsi_sandbox_hanami/.env +2 -0
  75. data/sandbox/itsi_sandbox_hanami/.gitignore +6 -0
  76. data/sandbox/itsi_sandbox_hanami/.rspec +1 -0
  77. data/sandbox/itsi_sandbox_hanami/Gemfile +49 -0
  78. data/sandbox/itsi_sandbox_hanami/Gemfile.lock +440 -0
  79. data/sandbox/itsi_sandbox_hanami/Guardfile +9 -0
  80. data/sandbox/itsi_sandbox_hanami/Procfile.dev +2 -0
  81. data/sandbox/itsi_sandbox_hanami/README.md +1 -0
  82. data/sandbox/itsi_sandbox_hanami/Rakefile +3 -0
  83. data/sandbox/itsi_sandbox_hanami/app/action.rb +12 -0
  84. data/sandbox/itsi_sandbox_hanami/app/actions/.keep +0 -0
  85. data/sandbox/itsi_sandbox_hanami/app/assets/css/app.css +5 -0
  86. data/sandbox/itsi_sandbox_hanami/app/assets/images/favicon.ico +0 -0
  87. data/sandbox/itsi_sandbox_hanami/app/assets/js/app.js +1 -0
  88. data/sandbox/itsi_sandbox_hanami/app/db/relation.rb +10 -0
  89. data/sandbox/itsi_sandbox_hanami/app/db/repo.rb +10 -0
  90. data/sandbox/itsi_sandbox_hanami/app/db/struct.rb +10 -0
  91. data/sandbox/itsi_sandbox_hanami/app/operation.rb +9 -0
  92. data/sandbox/itsi_sandbox_hanami/app/relations/.keep +0 -0
  93. data/sandbox/itsi_sandbox_hanami/app/repos/.keep +0 -0
  94. data/sandbox/itsi_sandbox_hanami/app/structs/.keep +0 -0
  95. data/sandbox/itsi_sandbox_hanami/app/templates/layouts/app.html.erb +14 -0
  96. data/sandbox/itsi_sandbox_hanami/app/view.rb +9 -0
  97. data/sandbox/itsi_sandbox_hanami/app/views/helpers.rb +10 -0
  98. data/sandbox/itsi_sandbox_hanami/bin/dev +8 -0
  99. data/sandbox/itsi_sandbox_hanami/config/app.rb +8 -0
  100. data/sandbox/itsi_sandbox_hanami/config/assets.js +16 -0
  101. data/sandbox/itsi_sandbox_hanami/config/db/migrate/.keep +0 -0
  102. data/sandbox/itsi_sandbox_hanami/config/db/seeds.rb +15 -0
  103. data/sandbox/itsi_sandbox_hanami/config/puma.rb +47 -0
  104. data/sandbox/itsi_sandbox_hanami/config/routes.rb +7 -0
  105. data/sandbox/itsi_sandbox_hanami/config/settings.rb +9 -0
  106. data/sandbox/itsi_sandbox_hanami/config.ru +5 -0
  107. data/sandbox/itsi_sandbox_hanami/db/.keep +0 -0
  108. data/sandbox/itsi_sandbox_hanami/lib/itsi_hanami/types.rb +11 -0
  109. data/sandbox/itsi_sandbox_hanami/lib/tasks/.keep +0 -0
  110. data/sandbox/itsi_sandbox_hanami/package-lock.json +946 -0
  111. data/sandbox/itsi_sandbox_hanami/package.json +8 -0
  112. data/sandbox/itsi_sandbox_hanami/spec/requests/root_spec.rb +11 -0
  113. data/sandbox/itsi_sandbox_hanami/spec/spec_helper.rb +9 -0
  114. data/sandbox/itsi_sandbox_hanami/spec/support/db/cleaning.rb +42 -0
  115. data/sandbox/itsi_sandbox_hanami/spec/support/db.rb +10 -0
  116. data/sandbox/itsi_sandbox_hanami/spec/support/features.rb +5 -0
  117. data/sandbox/itsi_sandbox_hanami/spec/support/operations.rb +8 -0
  118. data/sandbox/itsi_sandbox_hanami/spec/support/requests.rb +13 -0
  119. data/sandbox/itsi_sandbox_hanami/spec/support/rspec.rb +61 -0
  120. data/sandbox/itsi_sandbox_rack/Gemfile +17 -0
  121. data/sandbox/itsi_sandbox_rack/Gemfile.lock +153 -0
  122. data/sandbox/itsi_sandbox_rack/config.ru +18 -0
  123. data/sandbox/itsi_sandbox_rack_lint/Gemfile +7 -0
  124. data/sandbox/itsi_sandbox_rack_lint/Gemfile.lock +27 -0
  125. data/sandbox/itsi_sandbox_rack_lint/config.ru +3 -0
  126. data/sandbox/itsi_sandbox_rails/.dockerignore +51 -0
  127. data/sandbox/itsi_sandbox_rails/.gitattributes +9 -0
  128. data/sandbox/itsi_sandbox_rails/.github/dependabot.yml +12 -0
  129. data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +90 -0
  130. data/sandbox/itsi_sandbox_rails/.gitignore +34 -0
  131. data/sandbox/itsi_sandbox_rails/.kamal/hooks/docker-setup.sample +3 -0
  132. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-app-boot.sample +3 -0
  133. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-deploy.sample +14 -0
  134. data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-proxy-reboot.sample +3 -0
  135. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-app-boot.sample +3 -0
  136. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-build.sample +51 -0
  137. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-connect.sample +47 -0
  138. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-deploy.sample +109 -0
  139. data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-proxy-reboot.sample +3 -0
  140. data/sandbox/itsi_sandbox_rails/.kamal/secrets +17 -0
  141. data/sandbox/itsi_sandbox_rails/.rubocop.yml +8 -0
  142. data/sandbox/itsi_sandbox_rails/.ruby-version +1 -0
  143. data/sandbox/itsi_sandbox_rails/Dockerfile +72 -0
  144. data/sandbox/itsi_sandbox_rails/Gemfile +72 -0
  145. data/sandbox/itsi_sandbox_rails/Gemfile.lock +480 -0
  146. data/sandbox/itsi_sandbox_rails/README.md +24 -0
  147. data/sandbox/itsi_sandbox_rails/Rakefile +6 -0
  148. data/sandbox/itsi_sandbox_rails/app/assets/images/.keep +0 -0
  149. data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +10 -0
  150. data/sandbox/itsi_sandbox_rails/app/controllers/application_controller.rb +4 -0
  151. data/sandbox/itsi_sandbox_rails/app/controllers/concerns/.keep +0 -0
  152. data/sandbox/itsi_sandbox_rails/app/controllers/home_controller.rb +51 -0
  153. data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +41 -0
  154. data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +32 -0
  155. data/sandbox/itsi_sandbox_rails/app/helpers/application_helper.rb +2 -0
  156. data/sandbox/itsi_sandbox_rails/app/javascript/application.js +3 -0
  157. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/application.js +9 -0
  158. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/hello_controller.js +7 -0
  159. data/sandbox/itsi_sandbox_rails/app/javascript/controllers/index.js +4 -0
  160. data/sandbox/itsi_sandbox_rails/app/jobs/application_job.rb +7 -0
  161. data/sandbox/itsi_sandbox_rails/app/mailers/application_mailer.rb +4 -0
  162. data/sandbox/itsi_sandbox_rails/app/models/application_record.rb +3 -0
  163. data/sandbox/itsi_sandbox_rails/app/models/concerns/.keep +0 -0
  164. data/sandbox/itsi_sandbox_rails/app/models/post.rb +2 -0
  165. data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +28 -0
  166. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.html.erb +13 -0
  167. data/sandbox/itsi_sandbox_rails/app/views/layouts/mailer.text.erb +1 -0
  168. data/sandbox/itsi_sandbox_rails/app/views/pwa/manifest.json.erb +22 -0
  169. data/sandbox/itsi_sandbox_rails/app/views/pwa/service-worker.js +26 -0
  170. data/sandbox/itsi_sandbox_rails/bin/brakeman +7 -0
  171. data/sandbox/itsi_sandbox_rails/bin/bundle +109 -0
  172. data/sandbox/itsi_sandbox_rails/bin/dev +2 -0
  173. data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +14 -0
  174. data/sandbox/itsi_sandbox_rails/bin/importmap +4 -0
  175. data/sandbox/itsi_sandbox_rails/bin/jobs +6 -0
  176. data/sandbox/itsi_sandbox_rails/bin/kamal +27 -0
  177. data/sandbox/itsi_sandbox_rails/bin/rails +4 -0
  178. data/sandbox/itsi_sandbox_rails/bin/rake +4 -0
  179. data/sandbox/itsi_sandbox_rails/bin/rubocop +8 -0
  180. data/sandbox/itsi_sandbox_rails/bin/setup +34 -0
  181. data/sandbox/itsi_sandbox_rails/bin/thrust +5 -0
  182. data/sandbox/itsi_sandbox_rails/config/application.rb +61 -0
  183. data/sandbox/itsi_sandbox_rails/config/boot.rb +4 -0
  184. data/sandbox/itsi_sandbox_rails/config/cable.yml +17 -0
  185. data/sandbox/itsi_sandbox_rails/config/cache.yml +16 -0
  186. data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +1 -0
  187. data/sandbox/itsi_sandbox_rails/config/database.yml +40 -0
  188. data/sandbox/itsi_sandbox_rails/config/deploy.yml +116 -0
  189. data/sandbox/itsi_sandbox_rails/config/environment.rb +5 -0
  190. data/sandbox/itsi_sandbox_rails/config/environments/development.rb +72 -0
  191. data/sandbox/itsi_sandbox_rails/config/environments/production.rb +90 -0
  192. data/sandbox/itsi_sandbox_rails/config/environments/test.rb +53 -0
  193. data/sandbox/itsi_sandbox_rails/config/importmap.rb +7 -0
  194. data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +7 -0
  195. data/sandbox/itsi_sandbox_rails/config/initializers/content_security_policy.rb +25 -0
  196. data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +8 -0
  197. data/sandbox/itsi_sandbox_rails/config/initializers/inflections.rb +16 -0
  198. data/sandbox/itsi_sandbox_rails/config/locales/en.yml +31 -0
  199. data/sandbox/itsi_sandbox_rails/config/puma.rb +41 -0
  200. data/sandbox/itsi_sandbox_rails/config/queue.yml +18 -0
  201. data/sandbox/itsi_sandbox_rails/config/recurring.yml +10 -0
  202. data/sandbox/itsi_sandbox_rails/config/routes.rb +21 -0
  203. data/sandbox/itsi_sandbox_rails/config/storage.yml +34 -0
  204. data/sandbox/itsi_sandbox_rails/config.ru +7 -0
  205. data/sandbox/itsi_sandbox_rails/db/cable_schema.rb +11 -0
  206. data/sandbox/itsi_sandbox_rails/db/cache_schema.rb +14 -0
  207. data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +10 -0
  208. data/sandbox/itsi_sandbox_rails/db/queue_schema.rb +129 -0
  209. data/sandbox/itsi_sandbox_rails/db/schema.rb +23 -0
  210. data/sandbox/itsi_sandbox_rails/db/seeds.rb +9 -0
  211. data/sandbox/itsi_sandbox_rails/lib/tasks/.keep +0 -0
  212. data/sandbox/itsi_sandbox_rails/log/.keep +0 -0
  213. data/sandbox/itsi_sandbox_rails/public/400.html +114 -0
  214. data/sandbox/itsi_sandbox_rails/public/404.html +114 -0
  215. data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +114 -0
  216. data/sandbox/itsi_sandbox_rails/public/422.html +114 -0
  217. data/sandbox/itsi_sandbox_rails/public/500.html +114 -0
  218. data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
  219. data/sandbox/itsi_sandbox_rails/public/icon.svg +3 -0
  220. data/sandbox/itsi_sandbox_rails/public/robots.txt +1 -0
  221. data/sandbox/itsi_sandbox_rails/script/.keep +0 -0
  222. data/sandbox/itsi_sandbox_rails/storage/.keep +0 -0
  223. data/sandbox/itsi_sandbox_rails/test/application_system_test_case.rb +5 -0
  224. data/sandbox/itsi_sandbox_rails/test/controllers/.keep +0 -0
  225. data/sandbox/itsi_sandbox_rails/test/fixtures/files/.keep +0 -0
  226. data/sandbox/itsi_sandbox_rails/test/fixtures/posts.yml +9 -0
  227. data/sandbox/itsi_sandbox_rails/test/helpers/.keep +0 -0
  228. data/sandbox/itsi_sandbox_rails/test/integration/.keep +0 -0
  229. data/sandbox/itsi_sandbox_rails/test/mailers/.keep +0 -0
  230. data/sandbox/itsi_sandbox_rails/test/models/.keep +0 -0
  231. data/sandbox/itsi_sandbox_rails/test/models/post_test.rb +7 -0
  232. data/sandbox/itsi_sandbox_rails/test/system/.keep +0 -0
  233. data/sandbox/itsi_sandbox_rails/test/test_helper.rb +15 -0
  234. data/sandbox/itsi_sandbox_rails/tmp/.keep +0 -0
  235. data/sandbox/itsi_sandbox_rails/tmp/pids/.keep +0 -0
  236. data/sandbox/itsi_sandbox_rails/tmp/storage/.keep +0 -0
  237. data/sandbox/itsi_sandbox_rails/vendor/.keep +0 -0
  238. data/sandbox/itsi_sandbox_rails/vendor/javascript/.keep +0 -0
  239. data/sandbox/itsi_sandbox_roda/Gemfile +5 -0
  240. data/sandbox/itsi_sandbox_roda/Gemfile.lock +44 -0
  241. data/sandbox/itsi_sandbox_roda/config.ru +39 -0
  242. data/sandbox/itsi_sinatra/Gemfile +9 -0
  243. data/sandbox/itsi_sinatra/Gemfile.lock +81 -0
  244. data/sandbox/itsi_sinatra/app.rb +9 -0
  245. data/sandbox/pebble/docker-compose.yml +11 -0
  246. data/tasks.txt +4 -4
  247. metadata +199 -10
  248. data/gems/server/lib/itsi/signals.rb +0 -23
  249. data/gems/server/test/test_helper.rb +0 -7
@@ -1,6 +1,7 @@
1
1
  use super::bind::{Bind, BindAddress};
2
2
  use super::bind_protocol::BindProtocol;
3
3
  use super::io_stream::IoStream;
4
+ use super::serve_strategy::single_mode::RunningPhase;
4
5
  use super::tls::ItsiTlsAcceptor;
5
6
  use itsi_error::{ItsiError, Result};
6
7
  use itsi_tracing::info;
@@ -11,6 +12,7 @@ use std::{os::unix::net::UnixListener, path::PathBuf};
11
12
  use tokio::net::TcpListener as TokioTcpListener;
12
13
  use tokio::net::UnixListener as TokioUnixListener;
13
14
  use tokio::net::{unix, TcpStream, UnixStream};
15
+ use tokio::sync::watch::Receiver;
14
16
  use tokio_rustls::TlsAcceptor;
15
17
  use tokio_stream::StreamExt;
16
18
  use tracing::error;
@@ -23,45 +25,79 @@ pub(crate) enum Listener {
23
25
  }
24
26
 
25
27
  pub(crate) enum TokioListener {
26
- Tcp {
27
- listener: TokioTcpListener,
28
- host: String,
29
- port: u16,
30
- },
31
- TcpTls {
32
- listener: TokioTcpListener,
33
- acceptor: ItsiTlsAcceptor,
34
- host: String,
35
- port: u16,
36
- },
37
- Unix {
38
- listener: TokioUnixListener,
39
- },
40
- UnixTls {
41
- listener: TokioUnixListener,
42
- acceptor: ItsiTlsAcceptor,
43
- },
28
+ Tcp(TokioTcpListener),
29
+ TcpTls(TokioTcpListener, ItsiTlsAcceptor),
30
+ Unix(TokioUnixListener),
31
+ UnixTls(TokioUnixListener, ItsiTlsAcceptor),
32
+ }
33
+
34
+ #[derive(Debug, Clone)]
35
+ pub struct ListenerInfo {
36
+ pub host: String,
37
+ pub port: u16,
38
+ pub scheme: String,
44
39
  }
45
40
 
46
41
  impl TokioListener {
47
- pub fn unbind(self) {
42
+ pub fn listener_info(&self) -> ListenerInfo {
48
43
  match self {
49
- TokioListener::Tcp { listener, .. } => drop(listener.into_std().unwrap()),
50
- TokioListener::TcpTls { listener, .. } => drop(listener.into_std().unwrap()),
51
- TokioListener::Unix { listener } => drop(listener.into_std().unwrap()),
52
- TokioListener::UnixTls { listener, .. } => drop(listener.into_std().unwrap()),
53
- };
44
+ TokioListener::Tcp(listener) => ListenerInfo {
45
+ host: listener
46
+ .local_addr()
47
+ .unwrap()
48
+ .ip()
49
+ .to_canonical()
50
+ .to_string(),
51
+ port: listener.local_addr().unwrap().port(),
52
+ scheme: "http".to_string(),
53
+ },
54
+ TokioListener::TcpTls(listener, _) => ListenerInfo {
55
+ host: listener
56
+ .local_addr()
57
+ .unwrap()
58
+ .ip()
59
+ .to_canonical()
60
+ .to_string(),
61
+ port: listener.local_addr().unwrap().port(),
62
+ scheme: "https".to_string(),
63
+ },
64
+ TokioListener::Unix(listener) => ListenerInfo {
65
+ host: listener
66
+ .local_addr()
67
+ .unwrap()
68
+ .as_pathname()
69
+ .unwrap()
70
+ .to_str()
71
+ .unwrap()
72
+ .to_owned(),
73
+ port: 0,
74
+ scheme: "unix".to_string(),
75
+ },
76
+ TokioListener::UnixTls(listener, _) => ListenerInfo {
77
+ host: listener
78
+ .local_addr()
79
+ .unwrap()
80
+ .as_pathname()
81
+ .unwrap()
82
+ .to_str()
83
+ .unwrap()
84
+ .to_owned(),
85
+ port: 0,
86
+ scheme: "ssl".to_string(),
87
+ },
88
+ }
54
89
  }
90
+
55
91
  pub(crate) async fn accept(&self) -> Result<IoStream> {
56
92
  match self {
57
- TokioListener::Tcp { listener, .. } => TokioListener::accept_tcp(listener).await,
58
- TokioListener::TcpTls {
59
- listener, acceptor, ..
60
- } => TokioListener::accept_tls(listener, acceptor).await,
61
- TokioListener::Unix { listener, .. } => TokioListener::accept_unix(listener).await,
62
- TokioListener::UnixTls {
63
- listener, acceptor, ..
64
- } => TokioListener::accept_unix_tls(listener, acceptor).await,
93
+ TokioListener::Tcp(listener) => TokioListener::accept_tcp(listener).await,
94
+ TokioListener::TcpTls(listener, acceptor) => {
95
+ TokioListener::accept_tls(listener, acceptor).await
96
+ }
97
+ TokioListener::Unix(listener) => TokioListener::accept_unix(listener).await,
98
+ TokioListener::UnixTls(listener, acceptor) => {
99
+ TokioListener::accept_unix_tls(listener, acceptor).await
100
+ }
65
101
  }
66
102
  }
67
103
 
@@ -70,17 +106,24 @@ impl TokioListener {
70
106
  Self::to_tokio_io(Stream::TcpStream(tcp_stream), None).await
71
107
  }
72
108
 
73
- pub async fn spawn_state_task(&self) {
74
- if let TokioListener::TcpTls {
75
- acceptor: ItsiTlsAcceptor::Automatic(_acme_acceptor, state, _server_config),
76
- ..
77
- } = self
109
+ pub async fn spawn_state_task(&self, mut shutdown_receiver: Receiver<RunningPhase>) {
110
+ if let TokioListener::TcpTls(
111
+ _,
112
+ ItsiTlsAcceptor::Automatic(_acme_acceptor, state, _server_config),
113
+ ) = self
78
114
  {
79
115
  let mut state = state.lock().await;
80
116
  loop {
81
- match StreamExt::next(&mut *state).await {
82
- Some(event) => info!("Received acme event: {:?}", event),
83
- None => error!("Received no acme event"),
117
+ tokio::select! {
118
+ stream_event = StreamExt::next(&mut *state) => {
119
+ match stream_event {
120
+ Some(event) => info!("ACME Event: {:?}", event),
121
+ None => error!("Received no acme event"),
122
+ }
123
+ },
124
+ _ = shutdown_receiver.changed() => {
125
+ break;
126
+ }
84
127
  }
85
128
  }
86
129
  }
@@ -175,33 +218,6 @@ impl TokioListener {
175
218
  },
176
219
  }
177
220
  }
178
-
179
- pub(crate) fn scheme(&self) -> String {
180
- match self {
181
- TokioListener::Tcp { .. } => "http".to_string(),
182
- TokioListener::TcpTls { .. } => "https".to_string(),
183
- TokioListener::Unix { .. } => "http".to_string(),
184
- TokioListener::UnixTls { .. } => "https".to_string(),
185
- }
186
- }
187
-
188
- pub(crate) fn port(&self) -> u16 {
189
- match self {
190
- TokioListener::Tcp { port, .. } => *port,
191
- TokioListener::TcpTls { port, .. } => *port,
192
- TokioListener::Unix { .. } => 0,
193
- TokioListener::UnixTls { .. } => 0,
194
- }
195
- }
196
-
197
- pub(crate) fn host(&self) -> String {
198
- match self {
199
- TokioListener::Tcp { host, .. } => host.to_string(),
200
- TokioListener::TcpTls { host, .. } => host.to_string(),
201
- TokioListener::Unix { .. } => "unix".to_string(),
202
- TokioListener::UnixTls { .. } => "unix".to_string(),
203
- }
204
- }
205
221
  }
206
222
 
207
223
  enum Stream {
@@ -227,48 +243,22 @@ impl std::fmt::Display for SockAddr {
227
243
  }
228
244
 
229
245
  impl Listener {
230
- pub fn unbind(self) {
231
- match self {
232
- Listener::Tcp(listener) => drop(listener),
233
- Listener::TcpTls((listener, _)) => drop(listener),
234
- Listener::Unix(listener) => drop(listener),
235
- Listener::UnixTls((listener, _)) => drop(listener),
236
- };
237
- }
238
246
  pub fn to_tokio_listener(&self) -> TokioListener {
239
247
  match self {
240
- Listener::Tcp(listener) => TokioListener::Tcp {
241
- listener: TokioTcpListener::from_std(TcpListener::try_clone(listener).unwrap())
242
- .unwrap(),
243
- host: listener
244
- .local_addr()
245
- .unwrap()
246
- .ip()
247
- .to_canonical()
248
- .to_string(),
249
- port: listener.local_addr().unwrap().port(),
250
- },
251
- Listener::TcpTls((listener, acceptor)) => TokioListener::TcpTls {
252
- listener: TokioTcpListener::from_std(TcpListener::try_clone(listener).unwrap())
253
- .unwrap(),
254
- acceptor: acceptor.clone(),
255
- host: listener
256
- .local_addr()
257
- .unwrap()
258
- .ip()
259
- .to_canonical()
260
- .to_string(),
261
- port: listener.local_addr().unwrap().port(),
262
- },
263
- Listener::Unix(listener) => TokioListener::Unix {
264
- listener: TokioUnixListener::from_std(UnixListener::try_clone(listener).unwrap())
265
- .unwrap(),
266
- },
267
- Listener::UnixTls((listener, acceptor)) => TokioListener::UnixTls {
268
- listener: TokioUnixListener::from_std(UnixListener::try_clone(listener).unwrap())
269
- .unwrap(),
270
- acceptor: acceptor.clone(),
271
- },
248
+ Listener::Tcp(listener) => TokioListener::Tcp(
249
+ TokioTcpListener::from_std(TcpListener::try_clone(listener).unwrap()).unwrap(),
250
+ ),
251
+ Listener::TcpTls((listener, acceptor)) => TokioListener::TcpTls(
252
+ TokioTcpListener::from_std(TcpListener::try_clone(listener).unwrap()).unwrap(),
253
+ acceptor.clone(),
254
+ ),
255
+ Listener::Unix(listener) => TokioListener::Unix(
256
+ TokioUnixListener::from_std(UnixListener::try_clone(listener).unwrap()).unwrap(),
257
+ ),
258
+ Listener::UnixTls((listener, acceptor)) => TokioListener::UnixTls(
259
+ TokioUnixListener::from_std(UnixListener::try_clone(listener).unwrap()).unwrap(),
260
+ acceptor.clone(),
261
+ ),
272
262
  }
273
263
  }
274
264
  }
@@ -307,6 +297,7 @@ fn connect_tcp_socket(addr: IpAddr, port: u16) -> Result<TcpListener> {
307
297
  socket.set_nonblocking(true).ok();
308
298
  socket.set_nodelay(true).ok();
309
299
  socket.set_recv_buffer_size(262_144).ok();
300
+ info!("Binding to {:?}", socket_address);
310
301
  socket.bind(&socket_address.into())?;
311
302
  socket.listen(1024)?;
312
303
  Ok(socket.into())
@@ -4,7 +4,7 @@ use crate::{
4
4
  io_stream::IoStream,
5
5
  itsi_server::{RequestJob, Server},
6
6
  lifecycle_event::LifecycleEvent,
7
- listener::{Listener, TokioListener},
7
+ listener::{Listener, ListenerInfo},
8
8
  thread_worker::{build_thread_workers, ThreadWorker},
9
9
  },
10
10
  };
@@ -25,7 +25,10 @@ use std::{
25
25
  };
26
26
  use tokio::{
27
27
  runtime::{Builder as RuntimeBuilder, Runtime},
28
- sync::broadcast,
28
+ sync::{
29
+ broadcast,
30
+ watch::{self, Sender},
31
+ },
29
32
  task::JoinSet,
30
33
  };
31
34
  use tracing::instrument;
@@ -55,7 +58,7 @@ impl SingleMode {
55
58
  let (thread_workers, sender) = build_thread_workers(
56
59
  Pid::this(),
57
60
  NonZeroU8::try_from(server.threads).unwrap(),
58
- server.app,
61
+ server.app.clone(),
59
62
  server.scheduler_class.clone(),
60
63
  )?;
61
64
  Ok(Self {
@@ -80,6 +83,9 @@ impl SingleMode {
80
83
  }
81
84
 
82
85
  pub fn stop(&self) -> Result<()> {
86
+ self.lifecycle_channel
87
+ .send(LifecycleEvent::Shutdown)
88
+ .expect("Failed to send shutdown event");
83
89
  Ok(())
84
90
  }
85
91
 
@@ -87,18 +93,28 @@ impl SingleMode {
87
93
  pub fn run(self: Arc<Self>) -> Result<()> {
88
94
  let mut listener_task_set = JoinSet::new();
89
95
  let self_ref = Arc::new(self);
90
- self_ref.build_runtime().block_on(async {
96
+ let runtime = self_ref.build_runtime();
91
97
 
92
- for listener in self_ref.listeners.clone().iter() {
93
- let listener = Arc::new(listener.to_tokio_listener());
98
+ runtime.block_on(async {
99
+ let tokio_listeners = self_ref
100
+ .listeners
101
+ .iter()
102
+ .map(|list| Arc::new(list.to_tokio_listener()))
103
+ .collect::<Vec<_>>();
104
+ let (shutdown_sender, _) = watch::channel::<RunningPhase>(RunningPhase::Running);
105
+ for listener in tokio_listeners.iter() {
94
106
  let mut lifecycle_rx = self_ref.lifecycle_channel.subscribe();
107
+ let listener_info = Arc::new(listener.listener_info());
95
108
  let self_ref = self_ref.clone();
96
109
  let listener = listener.clone();
97
- let (shutdown_sender, mut shutdown_receiver) = tokio::sync::watch::channel::<RunningPhase>(RunningPhase::Running);
98
- let listener_clone = listener.clone();
110
+ let shutdown_sender = shutdown_sender.clone();
99
111
 
100
- tokio::spawn(async move {
101
- listener_clone.spawn_state_task().await;
112
+
113
+ let listener_clone = listener.clone();
114
+ let mut shutdown_receiver = shutdown_sender.clone().subscribe();
115
+ let shutdown_receiver_clone = shutdown_receiver.clone();
116
+ listener_task_set.spawn(async move {
117
+ listener_clone.spawn_state_task(shutdown_receiver_clone).await;
102
118
  });
103
119
 
104
120
  listener_task_set.spawn(async move {
@@ -107,8 +123,11 @@ impl SingleMode {
107
123
  tokio::select! {
108
124
  accept_result = listener.accept() => match accept_result {
109
125
  Ok(accept_result) => {
110
- if let Err(e) = strategy.serve_connection(accept_result, listener.clone(), shutdown_receiver.clone()).await {
111
- error!("Error in serve_connection {:?}", e)
126
+ match strategy.serve_connection(accept_result, listener_info.clone(), shutdown_receiver.clone()).await {
127
+ Ok(_) => {
128
+ debug!("Connection accepted and served");
129
+ },
130
+ Err(e) => error!("Error in serve_connection {:?}", e)
112
131
  }
113
132
  },
114
133
  Err(e) => debug!("Listener.accept failed {:?}", e),
@@ -130,24 +149,24 @@ impl SingleMode {
130
149
  }
131
150
  }
132
151
  }
133
- if let Ok(listener) = Arc::try_unwrap(listener){
134
- listener.unbind();
135
- }
136
152
  });
137
153
 
138
154
  }
139
155
 
140
156
  while let Some(_res) = listener_task_set.join_next().await {}
157
+
141
158
  });
159
+ runtime.shutdown_timeout(Duration::from_millis(100));
142
160
 
161
+ info!("Runtime has shut down");
143
162
  Ok(())
144
163
  }
145
164
 
146
165
  pub(crate) async fn serve_connection(
147
166
  &self,
148
167
  stream: IoStream,
149
- listener: Arc<TokioListener>,
150
- shutdown_channel: tokio::sync::watch::Receiver<RunningPhase>,
168
+ listener: Arc<ListenerInfo>,
169
+ shutdown_channel: watch::Receiver<RunningPhase>,
151
170
  ) -> Result<()> {
152
171
  let sender_clone = self.sender.clone();
153
172
  let addr = stream.addr();
@@ -209,12 +228,11 @@ impl SingleMode {
209
228
  pub async fn handle_lifecycle_event(
210
229
  &self,
211
230
  lifecycle_event: LifecycleEvent,
212
- shutdown_sender: tokio::sync::watch::Sender<RunningPhase>,
231
+ shutdown_sender: Sender<RunningPhase>,
213
232
  ) -> Result<()> {
233
+ info!("Handling lifecycle event: {:?}", lifecycle_event);
214
234
  if let LifecycleEvent::Shutdown = lifecycle_event {
215
- shutdown_sender
216
- .send(RunningPhase::ShutdownPending)
217
- .expect("Failed to send shutdown pending signal");
235
+ shutdown_sender.send(RunningPhase::ShutdownPending).ok();
218
236
  let deadline = Instant::now() + Duration::from_secs_f64(self.server.shutdown_timeout);
219
237
  for worker in &*self.thread_workers {
220
238
  worker.request_shutdown().await;
@@ -233,9 +251,7 @@ impl SingleMode {
233
251
  }
234
252
 
235
253
  info!("Sending shutdown signal");
236
- shutdown_sender
237
- .send(RunningPhase::Shutdown)
238
- .expect("Failed to send shutdown signal");
254
+ shutdown_sender.send(RunningPhase::Shutdown).ok();
239
255
  self.thread_workers.iter().for_each(|worker| {
240
256
  worker.poll_shutdown(deadline);
241
257
  });
@@ -10,6 +10,13 @@ pub static SIGNAL_HANDLER_CHANNEL: LazyLock<(
10
10
  broadcast::Receiver<LifecycleEvent>,
11
11
  )> = LazyLock::new(|| sync::broadcast::channel(5));
12
12
 
13
+ pub fn send_shutdown_event() {
14
+ SIGNAL_HANDLER_CHANNEL
15
+ .0
16
+ .send(LifecycleEvent::Shutdown)
17
+ .expect("Failed to send shutdown event");
18
+ }
19
+
13
20
  pub static SIGINT_COUNT: AtomicI8 = AtomicI8::new(0);
14
21
  fn receive_signal(signum: i32, _: sighandler_t) {
15
22
  SIGINT_COUNT.fetch_add(-1, std::sync::atomic::Ordering::SeqCst);
@@ -1,7 +1,7 @@
1
1
  use super::itsi_server::RequestJob;
2
2
  use crate::{request::itsi_request::ItsiRequest, ITSI_SERVER};
3
3
  use itsi_rb_helpers::{
4
- call_with_gvl, call_without_gvl, create_ruby_thread, kill_threads, HeapValue,
4
+ call_with_gvl, call_without_gvl, create_ruby_thread, kill_threads, HeapVal, HeapValue,
5
5
  };
6
6
  use itsi_tracing::{debug, error, info, warn};
7
7
  use magnus::{
@@ -52,7 +52,7 @@ pub struct TerminateWakerSignal(bool);
52
52
  pub fn build_thread_workers(
53
53
  pid: Pid,
54
54
  threads: NonZeroU8,
55
- app: Opaque<Value>,
55
+ app: HeapVal,
56
56
  scheduler_class: Option<String>,
57
57
  ) -> Result<(Arc<Vec<ThreadWorker>>, async_channel::Sender<RequestJob>)> {
58
58
  let (sender, receiver) = async_channel::bounded(20);
@@ -79,11 +79,10 @@ pub fn build_thread_workers(
79
79
  }
80
80
 
81
81
  pub fn load_app(
82
- app: Opaque<Value>,
82
+ app: HeapVal,
83
83
  scheduler_class: Option<String>,
84
84
  ) -> Result<(Opaque<Value>, Option<Opaque<Value>>)> {
85
85
  call_with_gvl(|ruby| {
86
- let app = app.get_inner_with(&ruby);
87
86
  let app = Opaque::from(
88
87
  app.funcall::<_, _, Value>(*ID_CALL, ())
89
88
  .expect("Couldn't load app"),
@@ -48,23 +48,26 @@ pub fn configure_tls(
48
48
  ) -> Result<ItsiTlsAcceptor> {
49
49
  let domains = query_params
50
50
  .get("domains")
51
- .map(|v| v.split(',').map(String::from).collect::<Vec<_>>());
51
+ .map(|v| v.split(',').map(String::from).collect::<Vec<_>>())
52
+ .or_else(|| query_params.get("domain").map(|v| vec![v.to_string()]));
52
53
 
53
- if query_params.get("cert").is_some_and(|c| c == "auto") {
54
+ if query_params.get("cert").is_some_and(|c| c == "acme") {
54
55
  if let Some(domains) = domains {
55
56
  let directory_url = &*ITSI_ACME_DIRECTORY_URL;
56
57
  info!(
57
58
  domains = format!("{:?}", domains),
58
59
  directory_url, "Requesting acme cert"
59
60
  );
61
+ let acme_contact_email = query_params
62
+ .get("acme_email")
63
+ .map(|s| s.to_string())
64
+ .or_else(|| (*ITSI_ACME_CONTACT_EMAIL).as_ref().ok().map(|s| s.to_string()))
65
+ .ok_or_else(|| itsi_error::ItsiError::ArgumentError(
66
+ "acme_cert query param or ITSI_ACME_CONTACT_EMAIL must be set before you can auto-generate let's encrypt certificates".to_string(),
67
+ ))?;
60
68
 
61
69
  let acme_config = AcmeConfig::new(domains)
62
- .contact([format!("mailto:{}", (*ITSI_ACME_CONTACT_EMAIL).as_ref().map_err(|_| {
63
- itsi_error::ItsiError::ArgumentError(
64
- "ITSI_ACME_CONTACT_EMAIL must be set before you can auto-generate production certificates"
65
- .to_string(),
66
- )
67
- })?)])
70
+ .contact([format!("mailto:{}", acme_contact_email)])
68
71
  .cache(LockedDirCache::new(&*ITSI_ACME_CACHE_DIR))
69
72
  .directory(directory_url);
70
73
 
@@ -186,7 +189,15 @@ pub fn load_private_key(path: &str) -> PrivateKeyDer<'static> {
186
189
  pub fn generate_ca_signed_cert(
187
190
  domains: Vec<String>,
188
191
  ) -> Result<(Vec<CertificateDer<'static>>, PrivateKeyDer<'static>)> {
189
- info!("Generating New Itsi CA - Self signed Certificate. Use `itsi ca export` to export the CA certificate for import into your local trust store.");
192
+ info!(
193
+ domains = format!("{}", domains.join(", ")),
194
+ "Self signed cert",
195
+ );
196
+ info!(
197
+ "Add {} to your system's trusted cert store to resolve certificate errors.",
198
+ format!("{}/itsi_dev_ca.crt", ITSI_LOCAL_CA_DIR.to_str().unwrap())
199
+ );
200
+ info!("Dev CA path can be overridden by setting env var: `ITSI_LOCAL_CA_DIR`.");
190
201
  let (ca_key_pem, ca_cert_pem) = get_or_create_local_dev_ca()?;
191
202
 
192
203
  let ca_kp = KeyPair::from_pem(&ca_key_pem).expect("Failed to load CA key");
@@ -198,10 +209,6 @@ pub fn generate_ca_signed_cert(
198
209
  let ee_key = KeyPair::generate_for(&rcgen::PKCS_ECDSA_P256_SHA256).unwrap();
199
210
  let mut ee_params = CertificateParams::default();
200
211
 
201
- info!(
202
- "Generated certificate will be valid for domains {:?}",
203
- domains
204
- );
205
212
  use std::net::IpAddr;
206
213
 
207
214
  ee_params.subject_alt_names = domains
@@ -1,11 +1,13 @@
1
1
  use std::env;
2
2
 
3
3
  use atty::{Stream, is};
4
+ use tracing::level_filters::LevelFilter;
4
5
  pub use tracing::{debug, error, info, trace, warn};
5
6
  pub use tracing_attributes::instrument; // Explicitly export from tracing-attributes
6
7
  use tracing_subscriber::{
7
- EnvFilter,
8
+ EnvFilter, Layer,
8
9
  fmt::{self, format},
10
+ layer::SubscriberExt,
9
11
  };
10
12
 
11
13
  #[instrument]
@@ -39,3 +41,18 @@ pub fn init() {
39
41
  .init();
40
42
  }
41
43
  }
44
+
45
+ pub fn run_silently<F, R>(f: F) -> R
46
+ where
47
+ F: FnOnce() -> R,
48
+ {
49
+ // Build a minimal subscriber that filters *everything* out
50
+ let no_op_subscriber =
51
+ tracing_subscriber::registry().with(fmt::layer().with_filter(LevelFilter::OFF));
52
+
53
+ // Turn that subscriber into a `Dispatch`
54
+ let no_op_dispatch = tracing::dispatcher::Dispatch::new(no_op_subscriber);
55
+
56
+ // Temporarily set `no_op_dispatch` as the *default* within this closure
57
+ tracing::dispatcher::with_default(&no_op_dispatch, f)
58
+ }
@@ -68,9 +68,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
68
68
 
69
69
  [[package]]
70
70
  name = "cc"
71
- version = "1.2.16"
71
+ version = "1.2.15"
72
72
  source = "registry+https://github.com/rust-lang/crates.io-index"
73
- checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
73
+ checksum = "c736e259eea577f443d5c86c304f9f4ae0295c43f3ba05c21f1d66b5f06001af"
74
74
  dependencies = [
75
75
  "shlex",
76
76
  ]
@@ -186,9 +186,9 @@ dependencies = [
186
186
 
187
187
  [[package]]
188
188
  name = "itoa"
189
- version = "1.0.15"
189
+ version = "1.0.14"
190
190
  source = "registry+https://github.com/rust-lang/crates.io-index"
191
- checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
191
+ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674"
192
192
 
193
193
  [[package]]
194
194
  name = "itsi-scheduler"
@@ -507,9 +507,9 @@ dependencies = [
507
507
 
508
508
  [[package]]
509
509
  name = "redox_syscall"
510
- version = "0.5.10"
510
+ version = "0.5.9"
511
511
  source = "registry+https://github.com/rust-lang/crates.io-index"
512
- checksum = "0b8c0c260b63a8219631167be35e6a988e9554dbd323f8bd08439c8ed1302bd1"
512
+ checksum = "82b568323e98e49e2a0899dcee453dd679fae22d69adf9b11dd508d1549b7e2f"
513
513
  dependencies = [
514
514
  "bitflags",
515
515
  ]
@@ -560,9 +560,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
560
560
 
561
561
  [[package]]
562
562
  name = "ring"
563
- version = "0.17.11"
563
+ version = "0.17.14"
564
564
  source = "registry+https://github.com/rust-lang/crates.io-index"
565
- checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73"
565
+ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7"
566
566
  dependencies = [
567
567
  "cc",
568
568
  "cfg-if",
@@ -586,9 +586,9 @@ checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
586
586
 
587
587
  [[package]]
588
588
  name = "ryu"
589
- version = "1.0.20"
589
+ version = "1.0.19"
590
590
  source = "registry+https://github.com/rust-lang/crates.io-index"
591
- checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f"
591
+ checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
592
592
 
593
593
  [[package]]
594
594
  name = "scopeguard"
@@ -624,9 +624,9 @@ dependencies = [
624
624
 
625
625
  [[package]]
626
626
  name = "serde_json"
627
- version = "1.0.140"
627
+ version = "1.0.139"
628
628
  source = "registry+https://github.com/rust-lang/crates.io-index"
629
- checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
629
+ checksum = "44f86c3acccc9c65b153fe1b85a3be07fe5515274ec9f0653b4a0875731c72a6"
630
630
  dependencies = [
631
631
  "itoa",
632
632
  "memchr",