Repository navigation
Replace multi_json with the json standard library - #613
Merged
ls-todd-lunter merged 1 commit intoOct 27, 2026
Merged
Conversation
multi_json picks between JSON backends at runtime. That mattered when the json gem was slow, but stdlib json is now as fast as or faster than oj on Docker API payloads, and calling it directly skips multi_json's per-call adapter dispatch. - JSON.parse / JSON.generate replace MultiJson.load / MultiJson.dump - JSON::ParserError replaces MultiJson::ParseError in Util.parse_json - symbolize_names: replaces multi_json's symbolize_keys: option - Drop the multi_json runtime dependency Signed-off-by: Tim Smith <tsmith84@proton.me>
ls-todd-lunter
added a commit
that referenced
this pull request
Oct 27, 2026
* Declare base64 as a runtime dependency so the gem loads on Ruby 3.4+ (#605) * Replace multi_json with the json standard library and drop the multi_json dependency (#613) * Keep the build context inside the build directory: symlinks are archived as symlinks rather than followed, and .dockerignore patterns can no longer reach outside the directory (#611) * Send platform as a query parameter on Container.create (#607) * Honor stdout: false and stderr: false in Container#exec (#609) * Request an HTTP upgrade when attaching to stdin so the attach no longer hangs (#610) * Memoize Connection#rootless? when the daemon is not rootless (#608) * Add gemspec metadata (source_code_uri, bug_tracker_uri, rubygems_mfa_required) and build the gem file list without git (#615) * Fix and update README examples and streaming read_timeout docs (#606, #585, #592) * Fix CI, test through Ruby 4.0 and Docker 28 and 29, and remove Travis, Code Climate and unmaintained test image leftovers (#604, #605, #614, #616)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Replaces
multi_jsonwith Ruby's standardjsonlibrary and drops themulti_jsonruntime dependency.multi_jsonpicks a JSON backend at runtime. That was useful when the json gem was slow, but current stdlibjsonmatches or beatsoj. Calling it directly also skips multi_json's per-call adapter dispatch, which is most of the cost on the small payloads the Docker API returns.MultiJson.load/MultiJson.dump→JSON.parse/JSON.generateMultiJson::ParseError→JSON::ParserErrorinDocker::Util.parse_json(it still re-raises asDocker::Error::UnexpectedResponseError, so callers see no change)symbolize_keys: true→ stdlib'ssymbolize_names: truePerformance
These payloads were captured from a real Docker 29.9 daemon (
/containers/json,/images/json,/containers/:id/json,/info). There's also a synthetic 200-container list to stand in for a busy host. The write case is a typicalContainer.createbody. I usedbenchmark-ipsinruby:*containers on arm64 Linux. Each report selects its multi_json adapter once, outside the timed loop.Iterations per second (higher is better):
Ruby 4.0.9, json 2.18.0 (bundled), oj 3.17.7
JSONMultiJson(json_gem)MultiJson(oj)Container.createbodyRuby 3.3.13 with current json 3.1.0, oj 3.17.7
JSONMultiJson(json_gem)MultiJson(oj)Container.createbodyWhat this shows:
jsongem. json ≥ 2.10 includes the rewritten parser that closes the gap, as the second table shows. I didn't add ajson >= 2.10constraint because that requires Ruby 2.7+, and CI still covers 2.4–2.6. It makes sense to add once the minimum Ruby version is raised.The harness also asserts that
JSONandMultiJson(json_gem adapter) give identical results on every payload.Benchmark script
Run with:
docker run --rm -v $PWD:/b ruby:4.0 bash -c 'gem install benchmark-ips multi_json oj && ruby /b/bench.rb /b/data'.data/holds the captured API responses.Testing
rake rspec) against Docker 29.9 in aruby:4.0container, on both this branch andmaster: 242 examples, 2 failures, 11 pending on each, and the same two failures. Both are environmental on a macOS Docker host and fail onmastertoo:container_spec.rb:680is the stdin exec hang from Attaching a container with stdin hangs on OSX #601, andimage_spec.rb:281is a local registry issue.util_spec,event_spec, anddocker_spec, which cover the changed parse and auth-header code: 69 examples, 0 failures.