serialbench 0.7.0 → 0.8.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1ad3e527e89762ad59203e00e1034b019a3b8a369e9251c52b6a3f389e9771e3
4
- data.tar.gz: dd68a1741b3a45d9b0f945ac4e23f35b48589c00dca63849f1223657da7f66d4
3
+ metadata.gz: 79e4440b243ee3e17d98b5fb83014761328304d3dff21336e77807767e70f761
4
+ data.tar.gz: 358f270ed322356b17f7994d9cb7f6705c106f2380230f1070a62341d3a50de8
5
5
  SHA512:
6
- metadata.gz: 17462212111e78b23dadc54c7527dadbd57f9e5c90803876c56a455285e612ded431cb0c77428f0f194ab1831579e99cdc9030bf134971c2c4fed56ff8fc5292
7
- data.tar.gz: 4f5e62c00d38f4790bf0cd1fe30da9ed0993bd175e5a995264c82dbf17ebf9311c232733d3b42519550a02775827ff1a055039caac3f912dc7604c6c7b461867
6
+ metadata.gz: 32244c3470ed9c206c1d22e59101fe062ed045d0b231d55a8504521a8d32ab9d0886dcbc4a07738adcdb0235620ae43b36cbee2c3c3e049ac60990fd3617066f
7
+ data.tar.gz: 8c92c1bd249fc841a433c9e1c7ef5e81d55733306ceea2920374ecb1d86b80252f04a57dd459009edbd61504332090fd0a902976608e303970902452fc73508f
@@ -23,7 +23,7 @@ fi
23
23
 
24
24
  DATE=$(date -u +%Y-%m-%d)
25
25
  TARGET_PATH="runs/${DATE}/${PLATFORM}-ruby-${RUBY_VERSION}.${FMT}.yaml"
26
- CONTENT=$(base64 < "$RESULTS_FILE")
26
+ CONTENT=$(base64 < "$RESULTS_FILE" | tr -d '\r\n')
27
27
 
28
28
  echo "Pushing ${TARGET_PATH} to serialbench/data..."
29
29
 
@@ -120,36 +120,6 @@ jobs:
120
120
  EOF
121
121
  shell: bash
122
122
 
123
- # Each format is an independent checkpoint with its own upload.
124
- # A failure in one format doesn't prevent the others from uploading.
125
- - name: Benchmark xml
126
- continue-on-error: true
127
- shell: bash
128
- env:
129
- GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
130
- run: |
131
- bundle exec serialbench environment execute \
132
- config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
133
- config/benchmarks/full-xml.yml \
134
- "results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml"
135
-
136
- - name: Upload xml
137
- if: ${{ !cancelled() }}
138
- uses: actions/upload-artifact@v4
139
- with:
140
- name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-xml
141
- path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml
142
- retention-days: 30
143
- if-no-files-found: warn
144
-
145
- - name: Push xml to data repo
146
- if: ${{ !cancelled() }}
147
- continue-on-error: true
148
- env:
149
- DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
150
- run: .github/scripts/push-to-data.sh xml ${{ matrix.ruby-version }} ${{ matrix.platform }}
151
- shell: bash
152
-
153
123
  - name: Benchmark json
154
124
  continue-on-error: true
155
125
  shell: bash
@@ -234,6 +204,37 @@ jobs:
234
204
  run: .github/scripts/push-to-data.sh toml ${{ matrix.ruby-version }} ${{ matrix.platform }}
235
205
  shell: bash
236
206
 
207
+ # Each format is an independent checkpoint with its own upload.
208
+ # A failure in one format doesn't prevent the others from uploading.
209
+ - name: Benchmark xml
210
+ continue-on-error: true
211
+ shell: bash
212
+ env:
213
+ GITHUB_RUNNER_PLATFORM: ${{ matrix.platform }}
214
+ run: |
215
+ bundle exec serialbench environment execute \
216
+ config/environments/ci-ruby-${{ matrix.ruby-version }}.yml \
217
+ config/benchmarks/full-xml.yml \
218
+ "results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml"
219
+
220
+ - name: Upload xml
221
+ if: ${{ !cancelled() }}
222
+ uses: actions/upload-artifact@v4
223
+ with:
224
+ name: benchmark-results-${{ matrix.platform }}-ruby-${{ matrix.ruby-version }}-xml
225
+ path: results/runs/ci-ruby-${{ matrix.ruby-version }}-${{ matrix.platform }}/xml
226
+ retention-days: 30
227
+ if-no-files-found: warn
228
+
229
+ - name: Push xml to data repo
230
+ if: ${{ !cancelled() }}
231
+ continue-on-error: true
232
+ env:
233
+ DATA_REPO_TOKEN: ${{ secrets.DATA_REPO_TOKEN }}
234
+ run: .github/scripts/push-to-data.sh xml ${{ matrix.ruby-version }} ${{ matrix.platform }}
235
+ shell: bash
236
+
237
+
237
238
  # Summary job
238
239
  summary:
239
240
  runs-on: ubuntu-latest
data/CONTEXT.md ADDED
@@ -0,0 +1,11 @@
1
+ # Serialbench domain glossary
2
+
3
+ - **Adapter** (a.k.a. serializer): one Ruby serialization library under measurement (nokogiri, leptris, oj, psych, toml-rb…). Registered per format in `Serializers::Serializers::REGISTER`. Its interface is the **capability set** (`capabilities` → `Set<Symbol>`); the `features` hash export derives from it.
4
+ - **Format**: xml, json, yaml, toml. One adapter belongs to exactly one format; one format has several adapters.
5
+ - **Operation**: one measured workload — `parsing`, `generation`, `xpath`, `streaming` (the `OPERATIONS` table in `BenchmarkRunner`), plus `memory` (profiled separately). Config `operations:` uses exactly these names; absent = run all; unknown name = error.
6
+ - **Result Leg**: one platform × ruby × format benchmark execution (one process, one config file). Produces one `results.yaml`.
7
+ - **Data Run**: one dated directory in the data repo (`runs/YYYY-MM-DD/`), holding one YAML file per environment × format. Append-only; the site's aggregator takes the latest run's data per environment.
8
+ - **Environment**: where a leg executes — `local`, `docker`, or `asdf` (`kind` in the environment config). Dispatched through `Runners.for`.
9
+ - **Environment key**: `{platform}-ruby-{version}` (e.g. `macos-26-ruby-3.4`) — the site's identity for a platform×ruby pair.
10
+ - **Capability**: a symbol in an adapter's capability set (`:xpath`, `:sax`, `:stax`, `:generate`, `:namespaces`…). Benchmarks filter adapters by capability; the site renders them as the capability strip.
11
+ - **Fixture**: the generated test document for a format × size (`small`/`medium`/`large`), built by `Serialbench::TestData`. `test_data/{size}.{format}` files override the generated one.
@@ -0,0 +1,9 @@
1
+ # ADR-0001: Three-repo split with incremental per-format pushes
2
+
3
+ Date: 2026-08-28
4
+
5
+ ## Context
6
+ The monolith coupled benchmark code, result storage, and site rendering; every publish was a batch job whose failure lost everything.
7
+
8
+ ## Decision
9
+ Three repos: `serialbench/serialbench` (gem), `serialbench/data` (append-only YAML runs), `serialbench/serialbench.github.io` (Astro site). Each Result Leg pushes its file to data via the Contents API immediately and triggers a site rebuild; legs are `continue-on-error` so one eviction never blocks the others.
@@ -0,0 +1,9 @@
1
+ # ADR-0002: Docker and ASDF runners stay
2
+
3
+ Date: 2026-08-28
4
+
5
+ ## Context
6
+ An architecture round deleted the docker/asdf runners as "unused by CI" (only LocalRunner executes in GitHub Actions).
7
+
8
+ ## Decision
9
+ Restore and keep them. The owner's requirement: every platform remains benchmarkable through the gem, not just what current CI exercises. Round 4 then repaired the asdf dispatch so the runner is actually reachable (`Runners.for`). Do not re-suggest deleting runners.
@@ -0,0 +1,9 @@
1
+ # ADR-0003: The capability set is the single adapter interface
2
+
3
+ Date: 2026-08-29
4
+
5
+ ## Context
6
+ Adapters declared capabilities through 49 individual `supports_X?` predicates, a parallel `features` hash, and (after a partial migration) a `capabilities` Set — three interfaces that could and did contradict (nokogiri's features denied streaming it has; rexml declared xpath without implementing `xpath_query`).
7
+
8
+ ## Decision
9
+ One source of truth: `capabilities` returns a `Set<Symbol>`; adapters override with `super | Set.new(...)`; the per-format `features` export derives from it; benchmark selection filters via `supports?`. New capability = one symbol. Do not reintroduce per-capability predicate methods.
@@ -0,0 +1,9 @@
1
+ # ADR-0004: Benchmark workflow keeps 12 explicit format steps
2
+
3
+ Date: 2026-08-30
4
+
5
+ ## Context
6
+ benchmark.yml repeats a benchmark/upload/push trio per format; a composite action could collapse 12 steps to 4.
7
+
8
+ ## Decision
9
+ Decline. `continue-on-error` is a caller-side property a composite cannot carry; the independent-checkpoint semantics would need re-implementation; each explicit step is a grep-able checkpoint during incident triage; the pipeline had a fragile week and the duplication is the price of the isolation property. Revisit only if a fifth format arrives.
@@ -0,0 +1,9 @@
1
+ # ADR-0005: Site loader stays a flat store
2
+
3
+ Date: 2026-08-29 (reaffirmed 2026-08-30)
4
+
5
+ ## Context
6
+ The site's `loadBenchmarks` returns a flat `BenchmarkStore` that components re-shape; a domain-query loader (leaderboard()/availability()/trend()) was proposed twice.
7
+
8
+ ## Decision
9
+ Defer. After the redesign the data layer is small, single-purpose modules (parser/aggregator/trend/versions, 18 tests) and no consumer friction has appeared. Revisit when a second dashboard view forces its own query shape.
@@ -0,0 +1,9 @@
1
+ # ADR-0006: One operations vocabulary
2
+
3
+ Date: 2026-08-29
4
+
5
+ ## Context
6
+ Benchmark configs declared `parse`/`generate`; the runner's OPERATIONS table used `parsing`/`generation`; `xpath` was in production configs but not the model's legal values; the config's `operations:` list was never read.
7
+
8
+ ## Decision
9
+ The OPERATIONS keys plus `memory` are the only legal names, end to end (config values, model validation, runner dispatch). Absent key = run everything; unknown name = `ArgumentError` with guidance. lutaml-model caveat: `default:` on a collection merges into deserialized values, so the everything-default lives in the runner, not the model.
@@ -135,6 +135,11 @@ module Serialbench
135
135
  results << result if result
136
136
  rescue StandardError => e
137
137
  puts " #{format}/#{serializer.name}: ERROR - #{e.message}"
138
+ ensure
139
+ # Free the previous adapter's documents before the next one
140
+ # parses + profiles; without this, six adapters' trees coexist
141
+ # and windows runners OOM during the xml memory pass.
142
+ GC.start
138
143
  end
139
144
  end
140
145
  end
@@ -75,7 +75,7 @@ module Serialbench
75
75
  name: serializer_singleton.name,
76
76
  format: serializer_singleton.format.to_s,
77
77
  version: serializer_singleton.version,
78
- features: serializer_singleton.features
78
+ features: serializer_singleton.features.transform_keys(&:to_s)
79
79
  )
80
80
  end
81
81
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Serialbench
4
- VERSION = '0.7.0'
4
+ VERSION = '0.8.0'
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serialbench
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose
@@ -264,6 +264,7 @@ files:
264
264
  - ".rspec"
265
265
  - ".rubocop.yml"
266
266
  - ".rubocop_todo.yml"
267
+ - CONTEXT.md
267
268
  - Gemfile
268
269
  - README.adoc
269
270
  - Rakefile
@@ -289,6 +290,12 @@ files:
289
290
  - docs/WEBSITE_COMPLETION_PLAN.md
290
291
  - docs/WINDOWS_LIBXML_FIX.md
291
292
  - docs/WINDOWS_SETUP.md
293
+ - docs/adr/0001-three-repo-split.md
294
+ - docs/adr/0002-runners-stay.md
295
+ - docs/adr/0003-capability-set.md
296
+ - docs/adr/0004-explicit-workflow-steps.md
297
+ - docs/adr/0005-site-loader-stays-flat.md
298
+ - docs/adr/0006-operations-vocabulary.md
292
299
  - exe/serialbench
293
300
  - lib/serialbench.rb
294
301
  - lib/serialbench/benchmark_runner.rb