Allow concurrent-ruby 1.3.x - #473
Conversation
|
This also blocks https://projects.theforeman.org/issues/39353. Once the relaxed concurrent-ruby constraint is released, Foreman can align its lock with the rest of the ecosystem without carrying a local workaround. |
|
Thanks both for the review! Pushed two follow-ups:
Note on The new CI run will need a workflow approval since it comes from a fork. |
It sort of does. concurrent-ruby-edge doesn't always honor its own namespace. We rely on |
|
Follow-up from CI on Summary of where the bats failure actually stands (test 5,
So under concurrent-ruby 1.3 + edge 0.7 the termination sequence stalls inside Question for you: is this porting something you'd want to handle on dynflow's side (given edge 0.7 rewrote the Actor machinery), or should this PR stay pinned-realying on that port landing separately? Either way we can keep the PR scope as-is and I'm happy to test patches. Also FYI the two unit-test failures in the 3.0/3.2 postgresql jobs are timing-sensitive (WithPollingSubPlans resume) plus one json-3.0.2 parse issue on Ruby 3.0 - happy to dig further if useful. |
|
I'm afraid I won't really be able to do any sort of porting in the immediate future. |
|
@adamruzicka I took care of the porting in #475 (Redmine #39799). The hang was not in Actor delivery itself: the termination sequence progressed through all components, but both the timeout watchdog and its asynchronous completion callback were scheduled on the saturated global IO executor. The separate PR keeps the future-based API, exposes a resolvable future, and runs only the bounded watchdog on a dedicated short-lived thread. I reproduced the PostgreSQL outage with concurrent-ruby 1.3.8 / concurrent-ruby-edge 0.7.2; the world exited after 80 seconds, and the Ruby 3.3/PostgreSQL suite passed with 402 runs and 1488 assertions. |
|
Perfect - #475 fixes exactly the node my CI tracing pointed at ( With #475 in place, this PR is scope-complete as a pure pin relaxation:
Happy to rebase here once #475 merges if you'd like the bats run re-verified against it. Thanks both for the quick turnaround! |
|
Follow-up: I added the two unit-CI fixes to #475 in
Verified on the combined #473 + #475 tree: Ruby 3.2/PostgreSQL full suite passes (402 runs, 1483 assertions), Ruby 3.0 and 3.2 targeted action/future-execution tests pass (41 runs, 131 assertions on each), and RuboCop is clean. Together with the PostgreSQL-outage verification already reported, rebasing this PR after #475 should address all three currently failing jobs. I did not open another helper PR. |
|
Sounds good - json 2 for Ruby < 3.2 plus the polling-clock ordering explains both matrix failures nicely. I'll rebase this branch once #475 lands so the bats + full matrix get validated on top of it. |
|
Could you please rebase? |
The ~> 1.1.3 pessimistic pin blocks every dependent (Foreman, smart-proxy plugins) from resolving the security-fixed concurrent-ruby releases: 1.3.7+ fixes CVE-2026-54906 and CVE-2026-54904. Relax the three related constraints: - dynflow.gemspec: concurrent-ruby '>= 1.1.3', '< 2.0' - dynflow.gemspec: concurrent-ruby-edge '~> 0.7.0' (0.7.x supports concurrent-ruby ~> 1.3, 0.6.x pins ~> 1.1.6) - Gemfile: concurrent-ruby-ext '~> 1.3.0' (ext releases follow the main gem: 1.3.8 is available) Code change: lib/dynflow.rb requires 'logger' explicitly. concurrent-ruby 1.1 loaded it as a side effect; 1.3 no longer does, so the global logger wiring in lib/dynflow.rb crashes with NameError on 1.3.x. Test evidence (ruby 3.3, concurrent-ruby 1.3.8 + edge 0.7.2 + ext 1.3.8): 397 tests of the suite pass. The full suite later hangs in the multi-executor dispatcher tests in our environment; the same hang reproduces on master with concurrent-ruby 1.1.10 (progressing through fewer tests), so it is pre-existing and unrelated to this change. Signed-off-by: log0u7 <70974447+log0u7@users.noreply.github.com>
Under concurrent-ruby 1.3 the persistence retry chain surfaces the fatal error after ~58s of polling rounds, past the previous 60s window. Keep the assertion, widen the window.
75880da to
c8603f1
Compare
|
Rebased on top of #475 (master |
|
Is the timeout increase in bats still needed? |
|
Yes, I believe so - even with #475 in, the fatal-persistence detection chain is slower under concurrent-ruby 1.3: jakduch measured the world exiting after ~80s (in the #475 verification note), and the original 60s window raced that even without the stall. The widened window is what let the bats job pass on this rebased branch. Happy to trim it to 120s if 180 feels generous - the assertion itself is unchanged. |
|
Yes. #475 fixes the deadlock, but it does not shorten the persistence retry budget. In my PostgreSQL outage reproduction with concurrent-ruby 1.3.8 and concurrent-ruby-edge 0.7.2, |
|
Thanks both for the fast review and the port work - great collaboration. One small note for the record: keeping the 180s window (jakduch's 120s floor + CI headroom, your call if you prefer trimming it in a follow-up). Looking forward to the gem release on rubygems so downstream (foreman #39353) can align its lock. |
Problem
The
~> 1.1.3pessimistic pin on concurrent-ruby (and the~> 0.6.0pin on concurrent-ruby-edge, which itself pinsconcurrent-ruby ~> 1.1.6) blocks every dependent from resolving the security-fixed concurrent-ruby releases. 1.3.7+ fixes CVE-2026-54906 and CVE-2026-54904; Foreman and the smart-proxy plugins (which pull dynflow) therefore ship a vulnerable concurrent-ruby with no resolver path to the fixed release.Fixes #474
Changes
dynflow.gemspec: concurrent-ruby'~> 1.1.3'->'>= 1.1.3', '< 2.0'dynflow.gemspec: concurrent-ruby-edge'~> 0.6.0'->'~> 0.7.0'(0.7.x supports concurrent-ruby~> 1.3; latest 0.7.2 released 2025-01)Gemfile: concurrent-ruby-ext'~> 1.1.3'->'~> 1.3.0'(ext releases follow the main gem, 1.3.8 available)lib/dynflow.rb:require 'logger'- concurrent-ruby 1.1 loaded logger as a side effect, 1.3 no longer does, so the global logger wiring crashed with NameError on 1.3.xTest evidence
ruby 3.3, concurrent-ruby 1.3.8 + edge 0.7.2 + ext 1.3.8: