feat: add UCRT runtime support - #411
Conversation
There was a problem hiding this comment.
Pull request overview
This PR extends Vajra’s Windows support to explicitly target the RubyInstaller UCRT/MinGW ABI, adding cross-platform socket/process abstractions in the native runtime, expanding Windows-focused e2e/C++ coverage, and updating docs and build tooling to reflect the supported Windows baseline and constraints (including rejecting MSVC Ruby).
Changes:
- Introduce Windows-oriented platform abstractions (socket/process handles, OpenSSL socket BIO glue) and wire them through listener/transport/request/runtime layers.
- Expand Windows validation via new/updated e2e specs, improved process signaling/diagnostics, and additional C++ tests.
- Update docs and packaging/build scripts to document UCRT support, reject MSVC Ruby, and adjust docs navigation/structure.
Reviewed changes
Copilot reviewed 114 out of 118 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| SECURITY.md | Reflow policy text (no behavioral change). |
| README.md | Update repository/docs links and formatting. |
| gems/vajra/vajra.gemspec | Exclude build artifacts from gem file list. |
| gems/vajra/spec/vajra/internal/tracing_spec.rb | Adjust tracing stubbing + add before-exit drain test. |
| gems/vajra/spec/vajra/internal/rack_execution_spec.rb | Add uninstall safety coverage when native load fails. |
| gems/vajra/spec/spec_helper.rb | Make coverage filtering/require behavior Windows- and installed-gem-aware. |
| gems/vajra/spec/e2e/vajra/vajra_worker_resilience_spec.rb | New Windows fault-injection resilience scenarios. |
| gems/vajra/spec/e2e/vajra/support/startup_helpers.rb | Windows-exclusive rebind logic for port reuse checks. |
| gems/vajra/spec/e2e/vajra/support/process_helpers.rb | Windows process-group signaling + better timeout diagnostics. |
| gems/vajra/spec/e2e/vajra/support/http_helpers.rb | Treat ECONNABORTED as a retryable/expected failure mode. |
| gems/vajra/spec/e2e/vajra/rack_hijack_integration_spec.rb | Improve timeout diagnostics and assertions. |
| gems/vajra/spec/e2e/vajra/h2c_integration_spec.rb | Batch WINDOW_UPDATE frames for fewer writes. |
| gems/vajra/spec/e2e/vajra/configuration_spec.rb | Windows-friendly span logging + test expectation tweaks. |
| gems/vajra/spec/e2e/spec_helper.rb | Windows process-group creation, banner parsing, installed-gem test support. |
| gems/vajra/spec/cpp/test_support.hpp | Switch test socket ownership helpers to SocketHandle-aware guard. |
| gems/vajra/spec/cpp/test_suites.hpp | Register new platform socket test suite. |
| gems/vajra/spec/cpp/server_test.cpp | Run platform socket tests in the C++ test binary. |
| gems/vajra/spec/cpp/server_lifecycle_test.cpp | Update socket invalid checks for SocketHandle semantics. |
| gems/vajra/spec/cpp/ruby_rack_transport_stub.cpp | Update interfaces to SocketHandle / invalid socket constant. |
| gems/vajra/spec/cpp/request_head_test.cpp | Remove POSIX pipe/unistd usage; use invalid socket sentinel. |
| gems/vajra/spec/cpp/rack_env_test.cpp | Update request context socket fd type to SocketHandle. |
| gems/vajra/spec/cpp/platform_socket_test.cpp | New tests for socket handle conversions and Windows BIO behavior. |
| gems/vajra/spec/cpp/CMakeLists.txt | Reject MSVC, set OpenSSL root for MinGW, link Windows libs, add new sources. |
| gems/vajra/README.md | Document Windows UCRT requirement and reflow text. |
| gems/vajra/performance/README.md | Update performance docs (Windows sampling notes, formatting). |
| gems/vajra/performance/Rakefile | Windows process control, robust server start/stop, richer RSS sampling, Windows-friendly vajra command. |
| gems/vajra/performance/Gemfile.lock | Add Windows UCRT platform gems. |
| gems/vajra/lib/vajra/internal/tracing.rb | Add before_worker_exit! and tighten drain-thread state reset. |
| gems/vajra/lib/vajra/internal/rack_execution.rb | Make uninstall safe when native extension APIs are unavailable. |
| gems/vajra/lib/vajra.rb | Add ABI checks/rejections on Windows and packaged-native lookup logic. |
| gems/vajra/Gemfile.lock | Add Windows platform deps (fiddle, tzinfo-data, nokogiri platform). |
| gems/vajra/Gemfile | Add Windows-scoped gems (fiddle, tzinfo-data). |
| gems/vajra/ext/vajra/vendor/nghttp2/UPSTREAM.md | Reflow upstream update instructions. |
| gems/vajra/ext/vajra/transport/tls_connection.hpp | Switch TLS socket types + add Windows BIO APIs. |
| gems/vajra/ext/vajra/transport/tls_connection.cpp | Implement Windows BIO method and replace poll-based waits with platform waits. |
| gems/vajra/ext/vajra/transport/connection.hpp | Switch Connection API to SocketHandle/SignedSize. |
| gems/vajra/ext/vajra/transport/connection.cpp | Use platform socket I/O + wait abstraction. |
| gems/vajra/ext/vajra/server.hpp | Expand server config surface and migrate listener fd to SocketHandle. |
| gems/vajra/ext/vajra/runtime/worker_pool.hpp | Replace pid_t with platform::ProcessId. |
| gems/vajra/ext/vajra/runtime/windows_worker_backend.hpp | New Windows worker supervisor interface header. |
| gems/vajra/ext/vajra/runtime/time_utils.cpp | Use gmtime_s on Windows. |
| gems/vajra/ext/vajra/runtime/runtime_state.hpp | Windows mapping APIs + ProcessId typing + shutdown query. |
| gems/vajra/ext/vajra/runtime/runtime_state.cpp | Windows shared mapping + Windows RSS sampling + shutdown query implementation. |
| gems/vajra/ext/vajra/runtime/runtime_logging.hpp | Use platform ProcessId and expanded boot logging signature. |
| gems/vajra/ext/vajra/runtime/native_runtime.hpp | Platform ProcessId types + Windows supervisor member. |
| gems/vajra/ext/vajra/runtime/native_runtime.cpp | Call tracing before-exit hook; use platform parent pid; rb_funcallv usage. |
| gems/vajra/ext/vajra/response/response_writer.hpp | Switch to SocketHandle for direct socket writes. |
| gems/vajra/ext/vajra/response/response_writer.cpp | Use platform setsockopt wrapper; guard POSIX headers. |
| gems/vajra/ext/vajra/request/request_processor.hpp | Add request-activity callback plumbing. |
| gems/vajra/ext/vajra/request/request_processor.cpp | Add request activity guard; use platform pid; Windows close handling. |
| gems/vajra/ext/vajra/request/request_head_reader.hpp | Switch read() to SocketHandle. |
| gems/vajra/ext/vajra/request/request_head_reader.cpp | Switch read() to SocketHandle (implementation signature). |
| gems/vajra/ext/vajra/request/request_head_parser.hpp | Include platform socket header and adjust includes/formatting. |
| gems/vajra/ext/vajra/request/request_context.hpp | Store client fd as SocketHandle with invalid sentinel. |
| gems/vajra/ext/vajra/request/request_body_reader.hpp | Switch to SocketHandle for fd-based reads. |
| gems/vajra/ext/vajra/request/request_body_reader.cpp | Use invalid-socket checks and remove POSIX-only includes. |
| gems/vajra/ext/vajra/request/http2_session.cpp | Platform pid + runtime shutdown exit conditions + improved write error reporting. |
| gems/vajra/ext/vajra/rack/ruby_rack_transport.hpp | Switch client fd to SocketHandle in APIs. |
| gems/vajra/ext/vajra/rack/ruby_rack_transport.cpp | Switch client fd to SocketHandle; use platform pid. |
| gems/vajra/ext/vajra/rack/ruby_execution_bridge.hpp | Switch client fd to SocketHandle for env construction. |
| gems/vajra/ext/vajra/rack/rack_request_executor.hpp | Switch client fd to SocketHandle across executor interfaces. |
| gems/vajra/ext/vajra/rack/rack_request_executor.cpp | Update start() signature to SocketHandle. |
| gems/vajra/ext/vajra/rack/native_input.cpp | Restructure read to keep Ruby longjmp out of C++-object lifetimes. |
| gems/vajra/ext/vajra/rack/http2_stream.cpp | Use rb_funcallv to avoid variadic rb_funcall usage patterns. |
| gems/vajra/ext/vajra/platform/socket.hpp | New cross-platform socket API/types and helpers. |
| gems/vajra/ext/vajra/platform/process.hpp | New cross-platform process id/handle API/types. |
| gems/vajra/ext/vajra/platform/process.cpp | Implement process id helpers for Windows/POSIX. |
| gems/vajra/ext/vajra/listener/listener_socket.hpp | Switch binding fd to SocketHandle. |
| gems/vajra/ext/vajra/listener/listener_socket.cpp | Replace raw socket ops with platform wrappers + Windows runtime init/nonblocking. |
| gems/vajra/ext/vajra/lifecycle/lifecycle_controller.hpp | Switch listener fd to SocketHandle and add dispatch-ready transition. |
| gems/vajra/ext/vajra/lifecycle/lifecycle_controller.cpp | SocketHandle integration + dispatch-ready lifecycle hook. |
| gems/vajra/ext/vajra/extconf.rb | Windows toolchain gating, OpenSSL root wiring, source selection per platform, and Windows libs. |
| gems/vajra/bin/ctest | Prefer Ninja/OpenSSL root autodetect on Windows CI/dev. |
| docs/pages/14-support.md | New “Professional Support” docs page. |
| docs/pages/14-glossary.md | Remove glossary page from docs. |
| docs/pages/11-api-reference.md | Adjust nav ordering and reflow content. |
| docs/pages/05-guides/10-development.md | Add Windows dev baseline and guides hierarchy metadata. |
| docs/pages/05-guides/08-compatibility.md | Document Windows UCRT support and limitations. |
| docs/pages/05-guides/07-upgrading.md | Guides hierarchy + reflow. |
| docs/pages/05-guides/06-migration.md | Guides hierarchy + reflow. |
| docs/pages/05-guides/05-performance.md | Guides hierarchy + Windows measurement notes. |
| docs/pages/05-guides/04-security.md | Guides hierarchy + reflow. |
| docs/pages/05-guides/03-production.md | Guides hierarchy + reflow. |
| docs/pages/05-guides/02-rack-compatibility.md | Guides hierarchy + reflow. |
| docs/pages/05-guides/01-observability.md | Guides hierarchy + reflow. |
| docs/pages/05-guides.md | New Guides index page for docs navigation. |
| docs/pages/05-frameworks.md | Reflow framework guidance. |
| docs/pages/04-command-reference.md | Reflow command reference content. |
| docs/pages/04-architecture/06-shutdown-drain.md | Add Windows-specific shutdown/drain notes. |
| docs/pages/04-architecture/05-rack-hijack.md | Reflow rack hijack architecture doc. |
| docs/pages/04-architecture/05-http2-stream-tunnels.md | Reflow stream tunnels doc. |
| docs/pages/04-architecture/04-protocols.md | Reflow protocols doc. |
| docs/pages/04-architecture/03-native-input.md | Reflow native input doc. |
| docs/pages/04-architecture/03-failure-modes.md | Add Windows-specific failure modes and code signposts. |
| docs/pages/04-architecture/02-runtime-model.md | Document Windows runtime backend parity model. |
| docs/pages/04-architecture/01-request-path.md | Update request path for socket handoff and Windows polling. |
| docs/pages/04-architecture.md | Add Windows architecture overview and update signposts. |
| docs/pages/03-configuration.md | Reflow configuration docs. |
| docs/pages/02-installation.md | Document Windows UCRT requirement and source-gem install behavior. |
| docs/index.md | Update docs entrypoint to point to Guides/Support and remove Glossary. |
| CONTRIBUTING.md | Reflow contributing guidance. |
| CODE_OF_CONDUCT.md | Reflow code of conduct text. |
| .github/pull_request_template.md | Reflow PR template guidance text. |
| .github/instructions/vajra.instructions.md | Reflow repository instructions. |
| .github/instructions/vajra-rbs.instructions.md | Reflow RBS instructions. |
| .github/copilot-instructions.md | Reflow Copilot instruction text. |
f00fb36 to
f78327a
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 114 out of 118 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
gems/vajra/ext/vajra/extconf.rb:31
windows_mingwcurrently matchescygwin, which makes Cygwin builds go down the Windows/Mingw path (e.g., linkingws2_32/psapiand selecting the Windows runtime sources). Since Cygwin Ruby is not otherwise supported/documented, this is likely to break builds onhost_os=cygwin*. Consider explicitly rejecting Cygwin and restricting the Windows path check tomingw.
f78327a to
9070b29
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 114 out of 118 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (3)
gems/vajra/spec/e2e/vajra/support/process_helpers.rb:116
Socket#setsockoptexpects an Integer or packed String value for the option payload; passingtruewill raise aTypeErroron Ruby (and would prevent the Windows port-binding helper from working). Use1(or0) for the boolean socket option value.
gems/vajra/lib/vajra.rb:111Vajra::NativeExtensionnow defines several additional public module functions (package_platform,ensure_supported_windows_abi!,packaged_native_root,validate_abi!, etc.), butgems/vajra/sig/vajra.rbsstill only declaresload!. This makes the RBS inaccurate and can break type validation. Either add the missing signatures insig/vajra.rbsor explicitly make the helper methods private so the public surface remains stable.
gems/vajra/spec/e2e/vajra/support/startup_helpers.rb:131- In the generated Windows rebound-listener script,
Socket#setsockoptis called withtrue. Ruby expects an Integer or packed String for the option payload;truewill raise aTypeErrorand make the readiness check fail on Windows. Pass1instead.
9070b29 to
97247bc
Compare
97247bc to
0e8f956
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 115 out of 119 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
gems/vajra/lib/vajra.rb:39
- On Windows,
ensure_supported_windows_abi!currently accepts any MinGW Ruby (RUBY_PLATFORM.include?('mingw')), including non-UCRT builds (e.g.,x64-mingw32). That contradicts the documented support surface in this PR (UCRT-only) and can lead to hard-to-diagnose native ABI/load failures later.
gems/vajra/ext/vajra/platform/socket.cpp:247 openssl_socket_descriptorunconditionally castsSocketHandletoint. On WindowsSOCKETis pointer-sized; a handle value that exceedsINT_MAXwould silently truncate and can become negative. Even if Windows currently avoidsSSL_set_fd, this helper should be safe/defensive because it’s used in tests and is a public platform utility.
0e8f956 to
2f125a5
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 120 out of 124 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
gems/vajra/spec/e2e/vajra/support/process_helpers.rb:10
- WINDOWS_SO_EXCLUSIVEADDRUSE is hard-coded to -5. That magic value is easy to get wrong across Ruby/Winsock versions and obscures intent; prefer using Ruby’s Socket::SO_EXCLUSIVEADDRUSE when available (with a fallback only if the constant is missing).
gems/vajra/ext/vajra/platform/socket.cpp:247 - On Windows, SOCKET is pointer-sized and may exceed INT_MAX. openssl_socket_descriptor currently casts SocketHandle to int without a range check, which can truncate and yield an invalid descriptor if this helper is ever called with a large handle.
2f125a5 to
46a92bc
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 121 out of 125 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
gems/vajra/ext/vajra/request/http2_session.cpp:1187
connection_.write()can fail with TLS connections afterTlsConnectionsetserrno(and may not updateWSAGetLastError). Using onlyplatform::socket_last_error()risks misclassifying the error (e.g., stale/zero WSA error), skipping retries, and emitting misleading diagnostics. Consider checking bothWSAGetLastErroranderrno, and include both in the exception message so Windows + TLS failures are actionable.
gems/vajra/ext/vajra/platform/socket.cpp:247- On Windows,
SOCKETis pointer-sized and not guaranteed to fit in anint.openssl_socket_descriptor()currently truncates viastatic_cast<int>(socket), which can mis-route I/O if the handle exceedsINT_MAX. This should reject oversized handles explicitly before handing them to OpenSSL/BIO APIs that takeint.
46a92bc to
d5ee87c
Compare
d5ee87c to
f24f2ec
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 122 out of 126 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
gems/vajra/lib/vajra/internal/rack_execution.rb:45
- Minor typo in the new comment: “Its at-exit cleanup” should be “It's at-exit cleanup”.
.github/pull_request_template.md:9 - The PR template examples were collapsed into a single line, which makes the guidance harder to scan and copy/paste correctly. Consider restoring the examples as a small bulleted list (and keep the HTML comment wrapper intact).
Supported title prefixes: feat:, bugfix:, docs:, release:, chore:, refactor:, test:, style:, ci:, perf:, build:
For example: feat: Add a new feature to the project bugfix: Fix bug in the project docs: Update documentation ci: Update GitHub Actions workflow build: Update package build configuration
A CLA is required for this pull request. Please read and sign the CLA at https://cla.developers.codevedas.com -->
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 122 out of 126 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (2)
gems/vajra/spec/e2e/vajra/support/startup_helpers.rb:131
Socket#setsockoptexpects the option value to be an Integer or a packed String; passingtruecan raiseTypeErroron Ruby. Use1(or0) for boolean socket options so the embedded script is portable on Windows.
gems/vajra/spec/e2e/vajra/support/process_helpers.rb:115Socket#setsockoptexpects the option value to be an Integer or a packed String; passingtruecan raiseTypeErroron Ruby. Use1(or0) for boolean socket options.
Closes: #326
Closes: #339
Closes: #352