itsi 0.1.11 → 0.1.12
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 +4 -4
- data/Cargo.lock +1535 -45
- data/{sandbox/itsi_itsi_file/Itsi.rb → Itsi.rb} +19 -13
- data/Rakefile +8 -7
- data/crates/itsi_error/src/lib.rs +9 -0
- data/crates/itsi_rb_helpers/Cargo.toml +1 -0
- data/crates/itsi_rb_helpers/src/heap_value.rs +18 -0
- data/crates/itsi_rb_helpers/src/lib.rs +34 -7
- data/crates/itsi_server/Cargo.toml +69 -30
- data/crates/itsi_server/src/lib.rs +79 -147
- data/crates/itsi_server/src/{body_proxy → ruby_types/itsi_body_proxy}/big_bytes.rs +10 -5
- data/crates/itsi_server/src/{body_proxy/itsi_body_proxy.rs → ruby_types/itsi_body_proxy/mod.rs} +22 -3
- data/crates/itsi_server/src/ruby_types/itsi_grpc_request.rs +147 -0
- data/crates/itsi_server/src/ruby_types/itsi_grpc_response.rs +19 -0
- data/crates/itsi_server/src/ruby_types/itsi_grpc_stream/mod.rs +216 -0
- data/{gems/server/ext/itsi_server/src/request/itsi_request.rs → crates/itsi_server/src/ruby_types/itsi_http_request.rs} +101 -117
- data/crates/itsi_server/src/{response/itsi_response.rs → ruby_types/itsi_http_response.rs} +72 -41
- data/crates/itsi_server/src/ruby_types/itsi_server/file_watcher.rs +225 -0
- data/crates/itsi_server/src/ruby_types/itsi_server/itsi_server_config.rs +355 -0
- data/crates/itsi_server/src/ruby_types/itsi_server.rs +82 -0
- data/crates/itsi_server/src/ruby_types/mod.rs +55 -0
- data/crates/itsi_server/src/server/bind.rs +13 -5
- data/crates/itsi_server/src/server/byte_frame.rs +32 -0
- data/crates/itsi_server/src/server/cache_store.rs +74 -0
- data/crates/itsi_server/src/server/itsi_service.rs +172 -0
- data/crates/itsi_server/src/server/lifecycle_event.rs +3 -0
- data/crates/itsi_server/src/server/listener.rs +102 -2
- data/crates/itsi_server/src/server/middleware_stack/middleware.rs +153 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/allow_list.rs +47 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_api_key.rs +58 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_basic.rs +82 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/auth_jwt.rs +321 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cache_control.rs +139 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/compression.rs +300 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/cors.rs +287 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/deny_list.rs +48 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/error_response.rs +127 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/etag.rs +191 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/grpc_service.rs +72 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/header_interpretation.rs +85 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/intrusion_protection.rs +195 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/log_requests.rs +82 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/mod.rs +82 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/proxy.rs +216 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/rate_limit.rs +124 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/redirect.rs +76 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/request_headers.rs +43 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/response_headers.rs +34 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/ruby_app.rs +93 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/static_assets.rs +162 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/string_rewrite.rs +158 -0
- data/crates/itsi_server/src/server/middleware_stack/middlewares/token_source.rs +12 -0
- data/crates/itsi_server/src/server/middleware_stack/mod.rs +315 -0
- data/crates/itsi_server/src/server/mod.rs +8 -1
- data/crates/itsi_server/src/server/process_worker.rs +38 -12
- data/crates/itsi_server/src/server/rate_limiter.rs +565 -0
- data/crates/itsi_server/src/server/request_job.rs +11 -0
- data/crates/itsi_server/src/server/serve_strategy/cluster_mode.rs +119 -42
- data/crates/itsi_server/src/server/serve_strategy/mod.rs +9 -6
- data/crates/itsi_server/src/server/serve_strategy/single_mode.rs +256 -111
- data/crates/itsi_server/src/server/signal.rs +19 -0
- data/crates/itsi_server/src/server/static_file_server.rs +984 -0
- data/crates/itsi_server/src/server/thread_worker.rs +139 -94
- data/crates/itsi_server/src/server/types.rs +43 -0
- data/crates/itsi_server/test.md +14 -0
- data/crates/itsi_tracing/Cargo.toml +1 -0
- data/crates/itsi_tracing/src/lib.rs +216 -45
- data/docs/.gitignore +7 -0
- data/docs/.gitpod.yml +15 -0
- data/docs/Itsi.rb +17 -0
- data/docs/content/_index.md +17 -0
- data/docs/content/about.md +6 -0
- data/docs/content/docs/_index.md +18 -0
- data/docs/content/docs/first-page.md +9 -0
- data/docs/content/docs/folder/_index.md +10 -0
- data/docs/content/docs/folder/leaf.md +7 -0
- data/docs/go.mod +5 -0
- data/docs/go.sum +2 -0
- data/docs/hugo.yaml +77 -0
- data/examples/static_assets_example.rb +83 -0
- data/gems/_index.md +18 -0
- data/gems/scheduler/CODE_OF_CONDUCT.md +7 -0
- data/gems/scheduler/Cargo.lock +75 -14
- data/gems/scheduler/README.md +5 -0
- data/gems/scheduler/_index.md +7 -0
- data/gems/scheduler/itsi-scheduler.gemspec +4 -1
- data/gems/scheduler/lib/itsi/scheduler/version.rb +1 -1
- data/gems/scheduler/lib/itsi/scheduler.rb +2 -2
- data/gems/scheduler/test/test_file_io.rb +0 -1
- data/gems/scheduler/test/test_itsi_scheduler.rb +1 -1
- data/gems/server/CHANGELOG.md +5 -0
- data/gems/server/CODE_OF_CONDUCT.md +7 -0
- data/gems/server/Cargo.lock +1536 -45
- data/gems/server/README.md +4 -0
- data/gems/server/_index.md +6 -0
- data/gems/server/exe/itsi +33 -74
- data/gems/server/itsi-server.gemspec +3 -2
- data/gems/server/lib/itsi/{request.rb → http_request.rb} +29 -5
- data/gems/server/lib/itsi/http_response.rb +39 -0
- data/gems/server/lib/itsi/server/Itsi.rb +11 -19
- data/gems/server/lib/itsi/server/config/dsl.rb +506 -0
- data/gems/server/lib/itsi/server/config.rb +103 -8
- data/gems/server/lib/itsi/server/default_app/default_app.rb +38 -0
- data/gems/server/lib/itsi/server/grpc_interface.rb +213 -0
- data/gems/server/lib/itsi/server/rack/handler/itsi.rb +8 -17
- data/gems/server/lib/itsi/server/rack_interface.rb +23 -4
- data/gems/server/lib/itsi/server/scheduler_interface.rb +1 -1
- data/gems/server/lib/itsi/server/scheduler_mode.rb +4 -0
- data/gems/server/lib/itsi/server/signal_trap.rb +7 -1
- data/gems/server/lib/itsi/server/version.rb +1 -1
- data/gems/server/lib/itsi/server.rb +74 -63
- data/gems/server/lib/itsi/standard_headers.rb +86 -0
- data/gems/server/test/helpers/test_helper.rb +12 -12
- data/gems/server/test/test_itsi_server.rb +2 -2
- data/lib/itsi/version.rb +1 -1
- data/sandbox/itsi_file/Gemfile +11 -0
- data/sandbox/itsi_file/Gemfile.lock +69 -0
- data/sandbox/itsi_file/Itsi.rb +276 -0
- data/sandbox/itsi_file/error.html +2 -0
- data/sandbox/itsi_file/organisations_controller.rb +20 -0
- data/sandbox/itsi_file/public/assets/image.png +0 -0
- data/sandbox/itsi_file/public/assets/index.html +1 -0
- data/sandbox/itsi_sandbox_hanami/Gemfile.lock +2 -2
- data/sandbox/itsi_sandbox_rack/Gemfile.lock +2 -2
- data/sandbox/itsi_sandbox_rack/config.ru +2 -15
- data/sandbox/itsi_sandbox_rails/.dockerignore +2 -5
- data/sandbox/itsi_sandbox_rails/.github/workflows/ci.yml +1 -1
- data/sandbox/itsi_sandbox_rails/.gitignore +2 -1
- data/sandbox/itsi_sandbox_rails/Dockerfile +6 -9
- data/sandbox/itsi_sandbox_rails/Gemfile +16 -22
- data/sandbox/itsi_sandbox_rails/Gemfile.lock +100 -225
- data/sandbox/itsi_sandbox_rails/app/assets/config/manifest.js +4 -0
- data/sandbox/itsi_sandbox_rails/app/assets/stylesheets/application.css +11 -6
- data/sandbox/itsi_sandbox_rails/app/channels/application_cable/channel.rb +4 -0
- data/sandbox/itsi_sandbox_rails/app/channels/application_cable/connection.rb +4 -0
- data/sandbox/itsi_sandbox_rails/app/controllers/live_controller.rb +7 -8
- data/sandbox/itsi_sandbox_rails/app/controllers/uploads_controller.rb +0 -3
- data/sandbox/itsi_sandbox_rails/app/views/layouts/application.html.erb +2 -7
- data/sandbox/itsi_sandbox_rails/bin/docker-entrypoint +3 -4
- data/sandbox/itsi_sandbox_rails/bin/setup +8 -5
- data/sandbox/itsi_sandbox_rails/config/application.rb +1 -35
- data/sandbox/itsi_sandbox_rails/config/cable.yml +3 -10
- data/sandbox/itsi_sandbox_rails/config/credentials.yml.enc +1 -1
- data/sandbox/itsi_sandbox_rails/config/database.yml +9 -19
- data/sandbox/itsi_sandbox_rails/config/environment.rb +1 -1
- data/sandbox/itsi_sandbox_rails/config/environments/development.rb +21 -12
- data/sandbox/itsi_sandbox_rails/config/environments/production.rb +49 -34
- data/sandbox/itsi_sandbox_rails/config/environments/test.rb +19 -5
- data/sandbox/itsi_sandbox_rails/config/initializers/assets.rb +5 -0
- data/sandbox/itsi_sandbox_rails/config/initializers/filter_parameter_logging.rb +1 -1
- data/sandbox/itsi_sandbox_rails/config/initializers/permissions_policy.rb +13 -0
- data/sandbox/itsi_sandbox_rails/config/puma.rb +2 -9
- data/sandbox/itsi_sandbox_rails/config.ru +0 -1
- data/sandbox/itsi_sandbox_rails/db/migrate/20250301041554_create_posts.rb +1 -1
- data/sandbox/itsi_sandbox_rails/db/schema.rb +2 -2
- data/sandbox/itsi_sandbox_rails/lib/assets/.keep +0 -0
- data/sandbox/itsi_sandbox_rails/public/404.html +66 -113
- data/sandbox/itsi_sandbox_rails/public/406-unsupported-browser.html +65 -113
- data/sandbox/itsi_sandbox_rails/public/422.html +66 -113
- data/sandbox/itsi_sandbox_rails/public/500.html +65 -113
- data/sandbox/itsi_sandbox_rails/public/icon.png +0 -0
- data/sandbox/itsi_sandbox_rails/public/icon.svg +2 -2
- data/sandbox/itsi_sandbox_rails/test/channels/application_cable/connection_test.rb +13 -0
- data/sandbox/itsi_sandbox_roda/Gemfile.lock +3 -10
- data/tasks.txt +72 -35
- metadata +89 -139
- data/crates/itsi_server/src/body_proxy/mod.rs +0 -2
- data/crates/itsi_server/src/request/itsi_request.rs +0 -298
- data/crates/itsi_server/src/request/mod.rs +0 -1
- data/crates/itsi_server/src/response/mod.rs +0 -1
- data/crates/itsi_server/src/server/itsi_server.rs +0 -288
- data/gems/scheduler/ext/itsi_error/Cargo.lock +0 -368
- data/gems/scheduler/ext/itsi_error/Cargo.toml +0 -11
- data/gems/scheduler/ext/itsi_error/src/from.rs +0 -68
- data/gems/scheduler/ext/itsi_error/src/lib.rs +0 -24
- data/gems/scheduler/ext/itsi_instrument_entry/Cargo.toml +0 -15
- data/gems/scheduler/ext/itsi_instrument_entry/src/lib.rs +0 -31
- data/gems/scheduler/ext/itsi_rb_helpers/Cargo.lock +0 -355
- data/gems/scheduler/ext/itsi_rb_helpers/Cargo.toml +0 -10
- data/gems/scheduler/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
- data/gems/scheduler/ext/itsi_rb_helpers/src/lib.rs +0 -201
- data/gems/scheduler/ext/itsi_scheduler/Cargo.toml +0 -24
- data/gems/scheduler/ext/itsi_scheduler/extconf.rb +0 -6
- data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
- data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
- data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
- data/gems/scheduler/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
- data/gems/scheduler/ext/itsi_scheduler/src/lib.rs +0 -38
- data/gems/scheduler/ext/itsi_server/Cargo.lock +0 -2956
- data/gems/scheduler/ext/itsi_server/Cargo.toml +0 -50
- data/gems/scheduler/ext/itsi_server/extconf.rb +0 -6
- data/gems/scheduler/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
- data/gems/scheduler/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
- data/gems/scheduler/ext/itsi_server/src/body_proxy/mod.rs +0 -2
- data/gems/scheduler/ext/itsi_server/src/env.rs +0 -43
- data/gems/scheduler/ext/itsi_server/src/lib.rs +0 -180
- data/gems/scheduler/ext/itsi_server/src/request/itsi_request.rs +0 -298
- data/gems/scheduler/ext/itsi_server/src/request/mod.rs +0 -1
- data/gems/scheduler/ext/itsi_server/src/response/itsi_response.rs +0 -357
- data/gems/scheduler/ext/itsi_server/src/response/mod.rs +0 -1
- data/gems/scheduler/ext/itsi_server/src/server/bind.rs +0 -174
- data/gems/scheduler/ext/itsi_server/src/server/bind_protocol.rs +0 -37
- data/gems/scheduler/ext/itsi_server/src/server/io_stream.rs +0 -104
- data/gems/scheduler/ext/itsi_server/src/server/itsi_server.rs +0 -288
- data/gems/scheduler/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
- data/gems/scheduler/ext/itsi_server/src/server/listener.rs +0 -318
- data/gems/scheduler/ext/itsi_server/src/server/mod.rs +0 -11
- data/gems/scheduler/ext/itsi_server/src/server/process_worker.rs +0 -203
- data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -260
- data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
- data/gems/scheduler/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -276
- data/gems/scheduler/ext/itsi_server/src/server/signal.rs +0 -74
- data/gems/scheduler/ext/itsi_server/src/server/thread_worker.rs +0 -399
- data/gems/scheduler/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
- data/gems/scheduler/ext/itsi_server/src/server/tls.rs +0 -265
- data/gems/scheduler/ext/itsi_tracing/Cargo.lock +0 -274
- data/gems/scheduler/ext/itsi_tracing/Cargo.toml +0 -16
- data/gems/scheduler/ext/itsi_tracing/src/lib.rs +0 -58
- data/gems/server/ext/itsi_error/Cargo.lock +0 -368
- data/gems/server/ext/itsi_error/Cargo.toml +0 -11
- data/gems/server/ext/itsi_error/src/from.rs +0 -68
- data/gems/server/ext/itsi_error/src/lib.rs +0 -24
- data/gems/server/ext/itsi_instrument_entry/Cargo.toml +0 -15
- data/gems/server/ext/itsi_instrument_entry/src/lib.rs +0 -31
- data/gems/server/ext/itsi_rb_helpers/Cargo.lock +0 -355
- data/gems/server/ext/itsi_rb_helpers/Cargo.toml +0 -10
- data/gems/server/ext/itsi_rb_helpers/src/heap_value.rs +0 -121
- data/gems/server/ext/itsi_rb_helpers/src/lib.rs +0 -201
- data/gems/server/ext/itsi_scheduler/Cargo.toml +0 -24
- data/gems/server/ext/itsi_scheduler/extconf.rb +0 -6
- data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_helpers.rs +0 -56
- data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/io_waiter.rs +0 -44
- data/gems/server/ext/itsi_scheduler/src/itsi_scheduler/timer.rs +0 -44
- data/gems/server/ext/itsi_scheduler/src/itsi_scheduler.rs +0 -308
- data/gems/server/ext/itsi_scheduler/src/lib.rs +0 -38
- data/gems/server/ext/itsi_server/Cargo.lock +0 -2956
- data/gems/server/ext/itsi_server/Cargo.toml +0 -50
- data/gems/server/ext/itsi_server/extconf.rb +0 -6
- data/gems/server/ext/itsi_server/src/body_proxy/big_bytes.rs +0 -104
- data/gems/server/ext/itsi_server/src/body_proxy/itsi_body_proxy.rs +0 -122
- data/gems/server/ext/itsi_server/src/body_proxy/mod.rs +0 -2
- data/gems/server/ext/itsi_server/src/env.rs +0 -43
- data/gems/server/ext/itsi_server/src/lib.rs +0 -180
- data/gems/server/ext/itsi_server/src/request/mod.rs +0 -1
- data/gems/server/ext/itsi_server/src/response/itsi_response.rs +0 -357
- data/gems/server/ext/itsi_server/src/response/mod.rs +0 -1
- data/gems/server/ext/itsi_server/src/server/bind.rs +0 -174
- data/gems/server/ext/itsi_server/src/server/bind_protocol.rs +0 -37
- data/gems/server/ext/itsi_server/src/server/io_stream.rs +0 -104
- data/gems/server/ext/itsi_server/src/server/itsi_server.rs +0 -288
- data/gems/server/ext/itsi_server/src/server/lifecycle_event.rs +0 -9
- data/gems/server/ext/itsi_server/src/server/listener.rs +0 -318
- data/gems/server/ext/itsi_server/src/server/mod.rs +0 -11
- data/gems/server/ext/itsi_server/src/server/process_worker.rs +0 -203
- data/gems/server/ext/itsi_server/src/server/serve_strategy/cluster_mode.rs +0 -260
- data/gems/server/ext/itsi_server/src/server/serve_strategy/mod.rs +0 -27
- data/gems/server/ext/itsi_server/src/server/serve_strategy/single_mode.rs +0 -276
- data/gems/server/ext/itsi_server/src/server/signal.rs +0 -74
- data/gems/server/ext/itsi_server/src/server/thread_worker.rs +0 -399
- data/gems/server/ext/itsi_server/src/server/tls/locked_dir_cache.rs +0 -132
- data/gems/server/ext/itsi_server/src/server/tls.rs +0 -265
- data/gems/server/ext/itsi_tracing/Cargo.lock +0 -274
- data/gems/server/ext/itsi_tracing/Cargo.toml +0 -16
- data/gems/server/ext/itsi_tracing/src/lib.rs +0 -58
- data/gems/server/lib/itsi/server/options_dsl.rb +0 -401
- data/gems/server/lib/itsi/stream_io.rb +0 -38
- data/location_dsl.rb +0 -381
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/docker-setup.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-app-boot.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-deploy.sample +0 -14
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/post-proxy-reboot.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-app-boot.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-build.sample +0 -51
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-connect.sample +0 -47
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-deploy.sample +0 -109
- data/sandbox/itsi_sandbox_rails/.kamal/hooks/pre-proxy-reboot.sample +0 -3
- data/sandbox/itsi_sandbox_rails/.kamal/secrets +0 -17
- data/sandbox/itsi_sandbox_rails/bin/dev +0 -2
- data/sandbox/itsi_sandbox_rails/bin/jobs +0 -6
- data/sandbox/itsi_sandbox_rails/bin/kamal +0 -27
- data/sandbox/itsi_sandbox_rails/bin/thrust +0 -5
- data/sandbox/itsi_sandbox_rails/config/cache.yml +0 -16
- data/sandbox/itsi_sandbox_rails/config/deploy.yml +0 -116
- data/sandbox/itsi_sandbox_rails/config/queue.yml +0 -18
- data/sandbox/itsi_sandbox_rails/config/recurring.yml +0 -10
- data/sandbox/itsi_sandbox_rails/db/cable_schema.rb +0 -11
- data/sandbox/itsi_sandbox_rails/db/cache_schema.rb +0 -14
- data/sandbox/itsi_sandbox_rails/db/queue_schema.rb +0 -129
- data/sandbox/itsi_sandbox_rails/public/400.html +0 -114
- data/sandbox/itsi_sandbox_rails/test/fixtures/posts.yml +0 -9
- data/sandbox/itsi_sandbox_rails/test/models/post_test.rb +0 -7
- /data/{sandbox/itsi_sandbox_rails/script/.keep → crates/_index.md} +0 -0
- /data/gems/server/lib/itsi/{index.html → server/default_app/index.html} +0 -0
@@ -1,24 +0,0 @@
|
|
1
|
-
[package]
|
2
|
-
name = "itsi-scheduler"
|
3
|
-
version = "0.1.0"
|
4
|
-
edition = "2021"
|
5
|
-
authors = ["Wouter Coppieters <wc@pico.net.nz>"]
|
6
|
-
license = "MIT"
|
7
|
-
publish = false
|
8
|
-
|
9
|
-
[lib]
|
10
|
-
crate-type = ["cdylib"]
|
11
|
-
|
12
|
-
[dependencies]
|
13
|
-
magnus = { version = "0.7.1", features = ["rb-sys", "bytes"] }
|
14
|
-
derive_more = { version = "2.0.1", features = ["debug"] }
|
15
|
-
itsi_tracing = { path = "../itsi_tracing" }
|
16
|
-
itsi_rb_helpers = { path = "../itsi_rb_helpers" }
|
17
|
-
itsi_error = { path = "../itsi_error" }
|
18
|
-
itsi_instrument_entry = { path = "../itsi_instrument_entry" }
|
19
|
-
parking_lot = "0.12.3"
|
20
|
-
mio = { version = "1.0.3", features = ["os-poll", "os-ext"] }
|
21
|
-
rb-sys = "0.9.105"
|
22
|
-
bytes = "1.10.1"
|
23
|
-
nix = "0.29.0"
|
24
|
-
tracing = "0.1.41"
|
@@ -1,56 +0,0 @@
|
|
1
|
-
use std::os::fd::RawFd;
|
2
|
-
|
3
|
-
use itsi_error::{ItsiError, Result};
|
4
|
-
use mio::Interest;
|
5
|
-
use nix::libc::{fcntl, poll, pollfd, F_GETFL, F_SETFL, O_NONBLOCK};
|
6
|
-
|
7
|
-
use super::Readiness;
|
8
|
-
|
9
|
-
pub fn set_nonblocking(fd: RawFd) -> itsi_error::Result<()> {
|
10
|
-
unsafe {
|
11
|
-
let flags = fcntl(fd, F_GETFL);
|
12
|
-
if flags < 0 {
|
13
|
-
return Err(ItsiError::ArgumentError(format!(
|
14
|
-
"fcntl(F_GETFL) error for fd {}: {}",
|
15
|
-
fd,
|
16
|
-
std::io::Error::last_os_error()
|
17
|
-
)));
|
18
|
-
}
|
19
|
-
let new_flags = flags | O_NONBLOCK;
|
20
|
-
if fcntl(fd, F_SETFL, new_flags) < 0 {
|
21
|
-
return Err(ItsiError::ArgumentError(format!(
|
22
|
-
"fcntl(F_SETFL) error for fd {}: {}",
|
23
|
-
fd,
|
24
|
-
std::io::Error::last_os_error()
|
25
|
-
)));
|
26
|
-
}
|
27
|
-
}
|
28
|
-
Ok(())
|
29
|
-
}
|
30
|
-
|
31
|
-
pub fn poll_readiness(fd: RawFd, events: i16) -> Option<Readiness> {
|
32
|
-
let mut pfd = pollfd {
|
33
|
-
fd,
|
34
|
-
events,
|
35
|
-
revents: 0,
|
36
|
-
};
|
37
|
-
let ret = unsafe { poll(&mut pfd as *mut pollfd, 1, 0) };
|
38
|
-
if ret > 0 {
|
39
|
-
return Some(Readiness(pfd.revents));
|
40
|
-
}
|
41
|
-
None
|
42
|
-
}
|
43
|
-
|
44
|
-
pub fn build_interest(events: i16) -> Result<Interest> {
|
45
|
-
let mut interest_opt = None;
|
46
|
-
if events & 1 != 0 {
|
47
|
-
interest_opt = Some(Interest::READABLE);
|
48
|
-
}
|
49
|
-
if events & 4 != 0 {
|
50
|
-
interest_opt = Some(match interest_opt {
|
51
|
-
Some(i) => i | Interest::WRITABLE,
|
52
|
-
None => Interest::WRITABLE,
|
53
|
-
});
|
54
|
-
}
|
55
|
-
interest_opt.ok_or_else(|| ItsiError::ArgumentError("No valid event specified".to_owned()))
|
56
|
-
}
|
@@ -1,44 +0,0 @@
|
|
1
|
-
use derive_more::Debug;
|
2
|
-
use mio::{event::Source, unix::SourceFd, Interest, Token};
|
3
|
-
use std::os::fd::RawFd;
|
4
|
-
|
5
|
-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
6
|
-
pub struct IoWaiter {
|
7
|
-
pub fd: RawFd,
|
8
|
-
pub readiness: i16,
|
9
|
-
pub token: Token,
|
10
|
-
}
|
11
|
-
|
12
|
-
impl IoWaiter {
|
13
|
-
pub fn new(fd: RawFd, readiness: i16, token: Token) -> Self {
|
14
|
-
Self {
|
15
|
-
fd,
|
16
|
-
readiness,
|
17
|
-
token,
|
18
|
-
}
|
19
|
-
}
|
20
|
-
}
|
21
|
-
|
22
|
-
impl Source for IoWaiter {
|
23
|
-
fn register(
|
24
|
-
&mut self,
|
25
|
-
registry: &mio::Registry,
|
26
|
-
token: Token,
|
27
|
-
interests: Interest,
|
28
|
-
) -> std::io::Result<()> {
|
29
|
-
SourceFd(&self.fd).register(registry, token, interests)
|
30
|
-
}
|
31
|
-
|
32
|
-
fn reregister(
|
33
|
-
&mut self,
|
34
|
-
registry: &mio::Registry,
|
35
|
-
token: Token,
|
36
|
-
interests: Interest,
|
37
|
-
) -> std::io::Result<()> {
|
38
|
-
SourceFd(&self.fd).reregister(registry, token, interests)
|
39
|
-
}
|
40
|
-
|
41
|
-
fn deregister(&mut self, registry: &mio::Registry) -> std::io::Result<()> {
|
42
|
-
SourceFd(&self.fd).deregister(registry)
|
43
|
-
}
|
44
|
-
}
|
@@ -1,44 +0,0 @@
|
|
1
|
-
use std::{
|
2
|
-
cmp::Ordering,
|
3
|
-
time::{Duration, Instant},
|
4
|
-
};
|
5
|
-
|
6
|
-
use mio::Token;
|
7
|
-
|
8
|
-
#[derive(Debug, Clone, PartialEq, Eq)]
|
9
|
-
pub struct Timer {
|
10
|
-
pub wake_time: Instant,
|
11
|
-
pub token: Token,
|
12
|
-
}
|
13
|
-
impl PartialOrd for Timer {
|
14
|
-
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
15
|
-
Some(self.cmp(other))
|
16
|
-
}
|
17
|
-
}
|
18
|
-
|
19
|
-
impl Ord for Timer {
|
20
|
-
fn cmp(&self, other: &Self) -> Ordering {
|
21
|
-
// Reverse the order: a timer with an earlier wake_time should be considered greater.
|
22
|
-
other
|
23
|
-
.wake_time
|
24
|
-
.cmp(&self.wake_time)
|
25
|
-
.then_with(|| other.token.cmp(&self.token))
|
26
|
-
}
|
27
|
-
}
|
28
|
-
|
29
|
-
impl Timer {
|
30
|
-
pub fn new(wake_in: Duration, token: Token) -> Self {
|
31
|
-
Self {
|
32
|
-
wake_time: Instant::now() + wake_in,
|
33
|
-
token,
|
34
|
-
}
|
35
|
-
}
|
36
|
-
|
37
|
-
pub fn is_due(&self) -> bool {
|
38
|
-
self.wake_time <= Instant::now()
|
39
|
-
}
|
40
|
-
|
41
|
-
pub(crate) fn duration(&self) -> Option<Duration> {
|
42
|
-
self.wake_time.checked_duration_since(Instant::now())
|
43
|
-
}
|
44
|
-
}
|
@@ -1,308 +0,0 @@
|
|
1
|
-
mod io_helpers;
|
2
|
-
mod io_waiter;
|
3
|
-
mod timer;
|
4
|
-
use io_helpers::{build_interest, poll_readiness, set_nonblocking};
|
5
|
-
use io_waiter::IoWaiter;
|
6
|
-
use itsi_error::ItsiError;
|
7
|
-
use itsi_rb_helpers::{call_without_gvl, create_ruby_thread};
|
8
|
-
use magnus::{
|
9
|
-
error::Result as MagnusResult,
|
10
|
-
value::{InnerValue, Opaque, ReprValue},
|
11
|
-
Module, RClass, Ruby, Value,
|
12
|
-
};
|
13
|
-
use mio::{Events, Poll, Token, Waker};
|
14
|
-
use parking_lot::{Mutex, RwLock};
|
15
|
-
use std::{
|
16
|
-
collections::{BinaryHeap, HashMap, VecDeque},
|
17
|
-
os::fd::RawFd,
|
18
|
-
sync::Arc,
|
19
|
-
time::Duration,
|
20
|
-
};
|
21
|
-
use timer::Timer;
|
22
|
-
use tracing::{debug, info, warn};
|
23
|
-
|
24
|
-
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
25
|
-
pub(crate) struct Readiness(i16);
|
26
|
-
|
27
|
-
impl std::fmt::Debug for ItsiScheduler {
|
28
|
-
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
29
|
-
f.debug_struct("ItsiScheduler").finish()
|
30
|
-
}
|
31
|
-
}
|
32
|
-
|
33
|
-
const WAKE_TOKEN: Token = Token(0);
|
34
|
-
|
35
|
-
#[magnus::wrap(class = "Itsi::Scheduler", free_immediately, size)]
|
36
|
-
pub(crate) struct ItsiScheduler {
|
37
|
-
timers: Mutex<BinaryHeap<Timer>>,
|
38
|
-
io_waiters: Mutex<HashMap<Token, IoWaiter>>,
|
39
|
-
registry: Mutex<HashMap<RawFd, VecDeque<IoWaiter>>>,
|
40
|
-
poll: Mutex<Poll>,
|
41
|
-
events: Mutex<Events>,
|
42
|
-
waker: Mutex<Waker>,
|
43
|
-
}
|
44
|
-
|
45
|
-
impl Default for ItsiScheduler {
|
46
|
-
fn default() -> Self {
|
47
|
-
let poll = Poll::new().unwrap();
|
48
|
-
let waker = Waker::new(poll.registry(), WAKE_TOKEN).unwrap();
|
49
|
-
let events = Events::with_capacity(1024);
|
50
|
-
|
51
|
-
ItsiScheduler {
|
52
|
-
timers: Mutex::new(BinaryHeap::new()),
|
53
|
-
io_waiters: Mutex::new(HashMap::new()),
|
54
|
-
registry: Mutex::new(HashMap::new()),
|
55
|
-
poll: Mutex::new(poll),
|
56
|
-
events: Mutex::new(events),
|
57
|
-
waker: Mutex::new(waker),
|
58
|
-
}
|
59
|
-
}
|
60
|
-
}
|
61
|
-
|
62
|
-
impl ItsiScheduler {
|
63
|
-
pub fn initialize(&self) {}
|
64
|
-
|
65
|
-
pub fn wake(&self) -> MagnusResult<()> {
|
66
|
-
self.waker.lock().wake().map_err(|_| {
|
67
|
-
magnus::Error::new(
|
68
|
-
magnus::exception::exception(),
|
69
|
-
"Failed to wake the scheduler",
|
70
|
-
)
|
71
|
-
})?;
|
72
|
-
Ok(())
|
73
|
-
}
|
74
|
-
pub fn register_io_wait(
|
75
|
-
&self,
|
76
|
-
io_obj: i32,
|
77
|
-
events: i16,
|
78
|
-
timeout: Option<f64>,
|
79
|
-
token: usize,
|
80
|
-
) -> MagnusResult<Option<i16>> {
|
81
|
-
debug!(
|
82
|
-
"Registering IO Wait for {:?}, {:?}, {:?}, {:?}",
|
83
|
-
io_obj, events, timeout, token
|
84
|
-
);
|
85
|
-
let fd: RawFd = io_obj;
|
86
|
-
|
87
|
-
let readiness = poll_readiness(fd, events).unwrap_or(Readiness(0));
|
88
|
-
if readiness == Readiness(events) {
|
89
|
-
return Ok(Some(readiness.0));
|
90
|
-
}
|
91
|
-
|
92
|
-
set_nonblocking(fd)?;
|
93
|
-
let interest = build_interest(events)?;
|
94
|
-
let token = Token(token);
|
95
|
-
let mut waiter = IoWaiter::new(fd, events, token);
|
96
|
-
self.io_waiters.lock().insert(token, waiter.clone());
|
97
|
-
let mut binding = self.registry.lock();
|
98
|
-
let queue = binding.entry(fd).or_default();
|
99
|
-
|
100
|
-
queue.push_back(waiter.clone());
|
101
|
-
|
102
|
-
if queue.len() == 1 {
|
103
|
-
self.poll
|
104
|
-
.lock()
|
105
|
-
.registry()
|
106
|
-
.register(&mut waiter, token, interest)
|
107
|
-
.map_err(|e| ItsiError::ArgumentError(format!("register error: {}", e)))?;
|
108
|
-
}
|
109
|
-
Ok(None)
|
110
|
-
}
|
111
|
-
|
112
|
-
pub fn start_timer(&self, timeout: Option<f64>, token: usize) {
|
113
|
-
if timeout.is_some_and(|t| t >= 0.0) {
|
114
|
-
let timer_entry = Timer::new(Duration::from_secs_f64(timeout.unwrap()), Token(token));
|
115
|
-
self.timers.lock().push(timer_entry);
|
116
|
-
}
|
117
|
-
}
|
118
|
-
pub fn has_pending_io(&self) -> bool {
|
119
|
-
!self.timers.lock().is_empty() || !self.io_waiters.lock().is_empty()
|
120
|
-
}
|
121
|
-
|
122
|
-
pub fn class_info(msg: String) {
|
123
|
-
info!(msg);
|
124
|
-
}
|
125
|
-
|
126
|
-
pub fn info(&self, msg: String) {
|
127
|
-
info!(msg);
|
128
|
-
}
|
129
|
-
|
130
|
-
pub fn warn(&self, msg: String) {
|
131
|
-
warn!(msg);
|
132
|
-
}
|
133
|
-
|
134
|
-
pub fn debug(&self, msg: String) {
|
135
|
-
debug!(msg);
|
136
|
-
}
|
137
|
-
|
138
|
-
pub fn fetch_due_events(&self) -> MagnusResult<Option<Vec<(usize, i16)>>> {
|
139
|
-
call_without_gvl(|| {
|
140
|
-
let timeout = if let Some(timer) = self.timers.lock().peek() {
|
141
|
-
timer.duration().or(Some(Duration::ZERO))
|
142
|
-
} else {
|
143
|
-
None
|
144
|
-
};
|
145
|
-
let mut due_fibers: Option<Vec<(usize, i16)>> = None;
|
146
|
-
let mut io_waiters = self.io_waiters.lock();
|
147
|
-
if !io_waiters.is_empty() || timeout.is_none() {
|
148
|
-
let mut events = self.events.lock();
|
149
|
-
{
|
150
|
-
let mut poll = self.poll.lock();
|
151
|
-
poll.poll(&mut events, timeout)
|
152
|
-
.map_err(|e| ItsiError::ArgumentError(format!("poll error: {}", e)))?;
|
153
|
-
};
|
154
|
-
|
155
|
-
for event in events.iter() {
|
156
|
-
let token = event.token();
|
157
|
-
if token == WAKE_TOKEN {
|
158
|
-
continue;
|
159
|
-
}
|
160
|
-
|
161
|
-
let waiter = io_waiters.remove(&token);
|
162
|
-
if waiter.is_none() {
|
163
|
-
continue;
|
164
|
-
}
|
165
|
-
let mut waiter = waiter.unwrap();
|
166
|
-
let mut evt_readiness = 0;
|
167
|
-
if event.is_readable() {
|
168
|
-
evt_readiness |= 1;
|
169
|
-
}
|
170
|
-
if event.is_priority() {
|
171
|
-
evt_readiness |= 2;
|
172
|
-
}
|
173
|
-
if event.is_writable() {
|
174
|
-
evt_readiness |= 4
|
175
|
-
}
|
176
|
-
self.poll
|
177
|
-
.lock()
|
178
|
-
.registry()
|
179
|
-
.deregister(&mut waiter)
|
180
|
-
.map_err(|_| {
|
181
|
-
ItsiError::ArgumentError("Failed to deregister".to_string())
|
182
|
-
})?;
|
183
|
-
|
184
|
-
due_fibers
|
185
|
-
.get_or_insert_default()
|
186
|
-
.push((waiter.token.0, evt_readiness));
|
187
|
-
|
188
|
-
let mut binding = self.registry.lock();
|
189
|
-
// Pop the current item for the current waiter off the queue
|
190
|
-
let queue = binding.get_mut(&(waiter.fd)).unwrap();
|
191
|
-
queue.pop_front();
|
192
|
-
|
193
|
-
if let Some(head) = queue.get_mut(0) {
|
194
|
-
// Register the next item in the queue if there is one.
|
195
|
-
let interest = build_interest(head.readiness)?;
|
196
|
-
self.poll
|
197
|
-
.lock()
|
198
|
-
.registry()
|
199
|
-
.register(head, head.token, interest)
|
200
|
-
.map_err(|_| {
|
201
|
-
ItsiError::ArgumentError("Failed to deregister".to_string())
|
202
|
-
})?;
|
203
|
-
} else {
|
204
|
-
// Otherwise we drop the queue altogether.
|
205
|
-
binding.remove(&waiter.fd);
|
206
|
-
}
|
207
|
-
}
|
208
|
-
return Ok(due_fibers);
|
209
|
-
}
|
210
|
-
Ok(None)
|
211
|
-
})
|
212
|
-
}
|
213
|
-
|
214
|
-
pub fn run_blocking_in_thread<T, F>(&self, ruby: &Ruby, work: F) -> MagnusResult<Option<T>>
|
215
|
-
where
|
216
|
-
T: Send + Sync + std::fmt::Debug + 'static,
|
217
|
-
F: FnOnce() -> Option<T> + Send + 'static,
|
218
|
-
{
|
219
|
-
let result: Arc<RwLock<Option<T>>> = Arc::new(RwLock::new(None));
|
220
|
-
let result_clone = Arc::clone(&result);
|
221
|
-
|
222
|
-
let current_fiber = Opaque::from(ruby.fiber_current());
|
223
|
-
let scheduler = Opaque::from(
|
224
|
-
ruby.module_kernel()
|
225
|
-
.const_get::<_, RClass>("Fiber")
|
226
|
-
.unwrap()
|
227
|
-
.funcall::<_, _, Value>("scheduler", ())
|
228
|
-
.unwrap(),
|
229
|
-
);
|
230
|
-
|
231
|
-
create_ruby_thread(move || {
|
232
|
-
call_without_gvl(|| {
|
233
|
-
let outcome = work();
|
234
|
-
*result_clone.write() = outcome;
|
235
|
-
});
|
236
|
-
|
237
|
-
let ruby = Ruby::get().unwrap();
|
238
|
-
scheduler
|
239
|
-
.get_inner_with(&ruby)
|
240
|
-
.funcall::<_, _, Value>("unblock", (None::<String>, current_fiber))
|
241
|
-
.unwrap();
|
242
|
-
});
|
243
|
-
|
244
|
-
scheduler
|
245
|
-
.get_inner_with(ruby)
|
246
|
-
.funcall::<_, _, Value>("block", (None::<Value>, None::<u64>))?;
|
247
|
-
|
248
|
-
let result_opt = Arc::try_unwrap(result).unwrap().write().take();
|
249
|
-
Ok(result_opt)
|
250
|
-
}
|
251
|
-
|
252
|
-
pub fn address_resolve(
|
253
|
-
ruby: &Ruby,
|
254
|
-
rself: &Self,
|
255
|
-
hostname: String,
|
256
|
-
) -> MagnusResult<Option<Vec<String>>> {
|
257
|
-
let result: Option<Vec<String>> = rself.run_blocking_in_thread(ruby, move || {
|
258
|
-
use std::net::ToSocketAddrs;
|
259
|
-
let addrs_res = (hostname.as_str(), 0).to_socket_addrs();
|
260
|
-
match addrs_res {
|
261
|
-
Ok(addrs) => {
|
262
|
-
let ips: Vec<String> = addrs.map(|s| s.ip().to_string()).collect();
|
263
|
-
Some(ips)
|
264
|
-
}
|
265
|
-
Err(_) => None,
|
266
|
-
}
|
267
|
-
})?;
|
268
|
-
Ok(result)
|
269
|
-
}
|
270
|
-
|
271
|
-
pub fn fetch_due_timers(&self) -> MagnusResult<Option<Vec<usize>>> {
|
272
|
-
call_without_gvl(|| {
|
273
|
-
let mut timers = self.timers.lock();
|
274
|
-
let mut io_waiters = self.io_waiters.lock();
|
275
|
-
let mut due_fibers: Option<Vec<usize>> = None;
|
276
|
-
while let Some(timer) = timers.peek() {
|
277
|
-
if timer.is_due() {
|
278
|
-
due_fibers.get_or_insert_default().push(timer.token.0);
|
279
|
-
if let Some(waiter) = io_waiters.remove(&timer.token) {
|
280
|
-
let mut binding = self.registry.lock();
|
281
|
-
// Pop the current item for the current waiter off the queue
|
282
|
-
let queue = binding.get_mut(&waiter.fd).unwrap();
|
283
|
-
queue.pop_front();
|
284
|
-
|
285
|
-
if let Some(head) = queue.get_mut(0) {
|
286
|
-
// Register the next item in the queue if there is one.
|
287
|
-
let interest = build_interest(head.readiness)?;
|
288
|
-
self.poll
|
289
|
-
.lock()
|
290
|
-
.registry()
|
291
|
-
.register(head, head.token, interest)
|
292
|
-
.map_err(|_| {
|
293
|
-
ItsiError::ArgumentError("Failed to deregister".to_string())
|
294
|
-
})?;
|
295
|
-
} else {
|
296
|
-
// Otherwise we drop the queue altogether.
|
297
|
-
binding.remove(&waiter.fd);
|
298
|
-
}
|
299
|
-
}
|
300
|
-
timers.pop();
|
301
|
-
} else {
|
302
|
-
break;
|
303
|
-
}
|
304
|
-
}
|
305
|
-
Ok(due_fibers)
|
306
|
-
})
|
307
|
-
}
|
308
|
-
}
|
@@ -1,38 +0,0 @@
|
|
1
|
-
use itsi_scheduler::ItsiScheduler;
|
2
|
-
use magnus::{function, method, Class, Error, Module, Object, Ruby};
|
3
|
-
mod itsi_scheduler;
|
4
|
-
|
5
|
-
#[magnus::init]
|
6
|
-
fn init(ruby: &Ruby) -> Result<(), Error> {
|
7
|
-
itsi_tracing::init();
|
8
|
-
let module = ruby.define_module("Itsi")?;
|
9
|
-
let scheduler = module.define_class("Scheduler", ruby.class_object())?;
|
10
|
-
scheduler.define_singleton_method("info", function!(ItsiScheduler::class_info, 1))?;
|
11
|
-
scheduler.define_alloc_func::<ItsiScheduler>();
|
12
|
-
scheduler.define_method("initialize", method!(ItsiScheduler::initialize, 0))?;
|
13
|
-
scheduler.define_method("wake", method!(ItsiScheduler::wake, 0))?;
|
14
|
-
scheduler.define_method(
|
15
|
-
"register_io_wait",
|
16
|
-
method!(ItsiScheduler::register_io_wait, 4),
|
17
|
-
)?;
|
18
|
-
scheduler.define_method("info", method!(ItsiScheduler::info, 1))?;
|
19
|
-
scheduler.define_method("debug", method!(ItsiScheduler::debug, 1))?;
|
20
|
-
scheduler.define_method("warn", method!(ItsiScheduler::warn, 1))?;
|
21
|
-
scheduler.define_method("start_timer", method!(ItsiScheduler::start_timer, 2))?;
|
22
|
-
scheduler.define_method(
|
23
|
-
"address_resolve",
|
24
|
-
method!(ItsiScheduler::address_resolve, 1),
|
25
|
-
)?;
|
26
|
-
scheduler.define_method("has_pending_io?", method!(ItsiScheduler::has_pending_io, 0))?;
|
27
|
-
|
28
|
-
scheduler.define_method(
|
29
|
-
"fetch_due_timers",
|
30
|
-
method!(ItsiScheduler::fetch_due_timers, 0),
|
31
|
-
)?;
|
32
|
-
scheduler.define_method(
|
33
|
-
"fetch_due_events",
|
34
|
-
method!(ItsiScheduler::fetch_due_events, 0),
|
35
|
-
)?;
|
36
|
-
|
37
|
-
Ok(())
|
38
|
-
}
|