Skip to content

Commit 6af963d

Browse files
authored
Merge pull request #867 from durable-workflow/rust-325-reference-2117
Rust #325: move the parity reference to published Server 2.11.7
2 parents d841887 + 99bbe28 commit 6af963d

15 files changed

Lines changed: 147 additions & 66 deletions

File tree

‎.github/workflows/native-image-parity.yml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ jobs:
4747
run: |
4848
set -euo pipefail
4949
bash scripts/ci/pull-images.sh \
50-
"$(jq -r '.server.images["linux/amd64"] | sub("^durableworkflow/server@"; "ghcr.io/durable-workflow/server@")' tests/Fixtures/ServerParityBaselines/php-2.11.5.json)" \
50+
"$(jq -r '.server.images["linux/amd64"] | sub("^durableworkflow/server@"; "ghcr.io/durable-workflow/server@")' tests/Fixtures/ServerParityBaselines/php-2.11.7.json)" \
5151
composer:2.10.3@sha256:da624c2c705d54e2f5a9bb77a5dc6c7d091711433ebefd7035672e84c2010fee
5252
5353
- name: Set up Docker Buildx

‎.github/workflows/server-parity.yml‎

Lines changed: 29 additions & 29 deletions
Large diffs are not rendered by default.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
# October 29, the parity reference moves to published 2.11.7
2+
3+
- **Before.** The Shared Server fixtures compared native and embedded
4+
against published Server 2.11.5 (Core 2.15.1).
5+
- **Reference.** Published Server 2.11.7, Core 2.15.7, as General published
6+
it and Security accepted it (#861):
7+
- source `f55f90e54a213872f1c164a1b22c082d859c18aa`;
8+
- index `sha256:96e3e7de8c58f31bfb1ef4d5bddddc2678f4684f5cb3505e6e9ddc6fa3f7f625`;
9+
- linux/amd64 `sha256:be7c2288ff935396262d743590530b204fac11b76582e56a525cc81a8da840d3`;
10+
- linux/arm64 `sha256:7dbc3db050fec05ea5cd10e07ac8399ecf3e285d593bca32979a2320f02a104f`.
11+
12+
`tests/Fixtures/ServerParityBaselines/php-2.11.7.json` records it. The
13+
SDK, CLI, Waterline and sample-app pins are unchanged.
14+
- **Why not 2.11.6.** A local survey of published 2.11.6 found that a
15+
repeated bridge-adapter update answered `500` (#861). 2.11.7 carries the
16+
fix (#862).
17+
- **Survey.** Every fixture in `tests/Fixtures/ServerParity` was recorded
18+
locally against the 2.11.7 amd64 image, SQLite, maintenance loop running,
19+
except `service-calls` (local SQLite lock pressure) and
20+
`visibility-current-runs` (it needs the published CLI artifact CI
21+
provides). Results:
22+
- 72 of 74 pass unchanged, `bridge-adapters` among them: 2.11.7 gives the
23+
intended answers at all three of its published-defect steps;
24+
- `schedule-catalog` fails locally the same way on 2.11.5;
25+
- `waterline-import` changes as expected (below).
26+
- **Expectation change.** Server #812 (#770) counts a v1 projection's
27+
history bytes as Core's `HistoryBudget::sizeOfEvent` does: the event
28+
type's bytes plus its payload as `json_encode` with
29+
`JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE`. That is the unit
30+
`DW_V2_LIMIT_HISTORY_TRANSACTION_BYTES` limits everywhere else.
31+
`waterline-import` records five `history_size_bytes` values:
32+
33+
| Export | 2.11.5 | 2.11.7 |
34+
| --- | --- | --- |
35+
| project | 5431 | 4713 |
36+
| running | 2683 | 2445 |
37+
| failed | 5425 | 4707 |
38+
| offsets | 6242 | 5336 |
39+
| bare | 1856 | 1668 |
40+
41+
No other value in that fixture changed.
42+
- **Native.** The prepared meter change (`e0ed32a6`, held since October 27
43+
for this move) counts each event the same way, for the byte limit and
44+
for the stored summary.
45+
- **Local checks before the pull request.**
46+
- `waterline-import` was recorded against a fresh 2.11.7 harness and
47+
against a native image built from this branch. Both pass, and
48+
`compare` accepts the pair. The 2.11.7 recording equals the stored
49+
contract observation (with the five new sizes) exactly.
50+
- The Rust library and integration suites pass (634 and 359).
51+
- The node unit suite passes, except the PHP image-context test,
52+
which fails the same way on a clean `main` checkout here because of
53+
local ignored state.
54+
- **Not changed here.** The `bridge-adapters` contract still accepts the
55+
published-defect answers of 2.11.1 to 2.11.5. 2.11.7 no longer gives
56+
them, so a later change can make that contract exact.

‎docs/rust-server-port.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ Updated October 27, 2026.
4444
and moved to published 2.11.5 (#815); the SQLite maintenance pause stays
4545
for `service-calls` only
4646
([checkpoint](rust-server-port-checkpoints/2026-10-27-reference-2115.md)).
47+
- The parity reference moves to published 2.11.7 (#863), with native's
48+
v1 projection history bytes in Core's canonical unit (#770)
49+
([checkpoint](rust-server-port-checkpoints/2026-10-29-reference-2117.md)).
4750
- [#814](https://github.com/durable-workflow/server/pull/814): the shared
4851
fixtures accept published PHP's typed `429 long_poll_capacity_exhausted`
4952
poll refusal, and retry a locked Composer install after a transient

‎rust/src/runtime/waterline_import.rs‎

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -609,14 +609,7 @@ fn events(source: &PhpArray, logs: &[PhpArray], signals: &[PhpArray], exceptions
609609
recorded_at,
610610
payload,
611611
};
612-
let size = object(vec![
613-
("event_type", text(event.event_type)),
614-
("recorded_at", optional(json_time(event.recorded_at))),
615-
("payload", event.payload.clone()),
616-
("sequence", Php::Int(event.sequence)),
617-
("id", text(&event.id)),
618-
]).encode(Flags { unescaped_slashes: true, ..Flags::default() }).len();
619-
bytes = bytes.checked_add(size).unwrap_or(usize::MAX);
612+
bytes = bytes.checked_add(event_bytes(&event)).unwrap_or(usize::MAX);
620613
if let Some(error) = exceeded(limits, 0, bytes) {
621614
return Err((error, index + 1));
622615
}
@@ -625,6 +618,15 @@ fn events(source: &PhpArray, logs: &[PhpArray], signals: &[PhpArray], exceptions
625618
Ok((built, bytes))
626619
}
627620

621+
/// Core's history-transaction byte unit, `HistoryBudget::sizeOfEvent`: the
622+
/// event type's bytes plus its payload as `json_encode` with
623+
/// `JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE` writes it (Server #770).
624+
/// The event's id, sequence and time are not counted.
625+
fn event_bytes(event: &Event) -> usize {
626+
event.event_type.len()
627+
+ event.payload.encode(Flags { unescaped_slashes: true, unescaped_unicode: true, ..Flags::default() }).len()
628+
}
629+
628630
/// `report`: the projection report, with the first error's reason, message
629631
/// and remediation at the top of a rejection, then `extra`.
630632
fn report(outcome: &Outcome, status: &str, extra: Vec<(&str, Value)>) -> Value {
@@ -1352,13 +1354,7 @@ mod tests {
13521354
let (outcome, start) = events_built(|| normalize_bounded("src-1", source, None, &limited(None, None)));
13531355
let Outcome::Valid(all) = outcome else { panic!("valid") };
13541356
assert_eq!(start, all.events.len());
1355-
let first = |count: usize| all.events[..count].iter().map(|event| object(vec![
1356-
("event_type", text(event.event_type)),
1357-
("recorded_at", optional(json_time(event.recorded_at))),
1358-
("payload", event.payload.clone()),
1359-
("sequence", Php::Int(event.sequence)),
1360-
("id", text(&event.id)),
1361-
]).encode(Flags { unescaped_slashes: true, ..Flags::default() }).len()).sum::<usize>();
1357+
let first = |count: usize| all.events[..count].iter().map(event_bytes).sum::<usize>();
13621358
let (outcome, built) = events_built(|| normalize_bounded("src-1", source, None, &limited(None, Some(first(4)))));
13631359
assert!(matches!(outcome, Outcome::TooLarge { built: 5, .. }));
13641360
assert_eq!(built, 5);
@@ -1367,7 +1363,8 @@ mod tests {
13671363
#[test]
13681364
fn events_and_history_size_follow_php() {
13691365
// PHP 2.11.1: LegacyV1Projection::normalize('src-1', bare source, 'ns-1')
1370-
// printed these event encodings (json_encode, JSON_UNESCAPED_SLASHES).
1366+
// printed these event encodings (json_encode, JSON_UNESCAPED_SLASHES),
1367+
// which fix the events' ids and payloads.
13711368
let source = super::super::php_value::decode(br#"{"operator_id":"v1:4501","engine_source":"v1","class":"App\\Workflows\\Legacy\\Bare","status":"completed"}"#)
13721369
.unwrap();
13731370
let Outcome::Valid(normalized) = normalize("src-1", source.array().unwrap(), Some("ns-1")) else { panic!("valid") };
@@ -1380,7 +1377,11 @@ mod tests {
13801377
]).encode(Flags { unescaped_slashes: true, ..Flags::default() })).collect();
13811378
assert_eq!(encoded[0].len(), 1374, "{}", encoded[0]);
13821379
assert_eq!(encoded[1].len(), 496, "{}", encoded[1]);
1383-
assert_eq!(normalized.history_size_bytes, 1870);
1380+
// Server #812's LegacyV1Projection::normalize on Core 2.15's
1381+
// HistoryBudget::sizeOfEvent counted 1280 and 402 bytes for these
1382+
// events: their types and payloads, not their ids, sequences or times.
1383+
assert_eq!(normalized.events.iter().map(event_bytes).collect::<Vec<_>>(), [1280, 402]);
1384+
assert_eq!(normalized.history_size_bytes, 1682);
13841385
assert_eq!(normalized.workflow_id, "v1:src-1:c8c25815a3332910ba072598");
13851386
assert_eq!(normalized.run_id, "b0ee56b2b89080ea9181490e2f");
13861387
assert_eq!(normalized.events[0].id, "9730c0bb4149e0a120cc8a8d7e");

‎scripts/conformance/server-parity.mjs‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Requires Node 20+ and PHP 8.3+ with the locked adapter installed. Each target
4444
must have its own isolated, already bootstrapped database. Set DW_PARITY_TOKEN
4545
for the HTTP target; it is never recorded. Use the same --prefix on all targets
4646
and a fresh database or prefix for a new run. --artifacts selects the exact
47-
consumer tuple; the default is tests/Fixtures/ServerParityBaselines/php-2.11.5.json.
47+
consumer tuple; the default is tests/Fixtures/ServerParityBaselines/php-2.11.7.json.
4848
Repeat --fixture PATH to record or compare an explicitly selected candidate
4949
set. --database-resource-limits accepts inspected memory_bytes and
5050
memory_swap_bytes as a JSON object; comparisons require equal effective
@@ -81,7 +81,7 @@ try {
8181
}
8282
const record = {
8383
schema: 'durable-workflow.server-parity-record/v1', target: values.target, mode: values.mode,
84-
runner_revision: values['runner-revision'], artifacts: json(values.artifacts ?? resolve(root, 'tests/Fixtures/ServerParityBaselines/php-2.11.5.json')),
84+
runner_revision: values['runner-revision'], artifacts: json(values.artifacts ?? resolve(root, 'tests/Fixtures/ServerParityBaselines/php-2.11.7.json')),
8585
started_at: new Date().toISOString(), outcome: 'runner-blocked', fixture_hashes: hashes, cases: [],
8686
database_resource_limits: parseDatabaseResourceLimits(values['database-resource-limits']),
8787
};

‎scripts/conformance/server-parity/README.md‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ Docker kill and verifies exit code 137 before restarting the native process.
285285

286286
For an adapter installed elsewhere, set `DW_PARITY_SDK_AUTOLOAD` to its locked
287287
`vendor/autoload.php`. `--artifacts` selects a frozen tuple manifest. The default
288-
is `tests/Fixtures/ServerParityBaselines/php-2.11.5.json`; its SDK version must match
288+
is `tests/Fixtures/ServerParityBaselines/php-2.11.7.json`; its SDK version must match
289289
the installed lock. A frozen tuple does not prove every listed consumer ran.
290290
The original `tests/Fixtures/ServerParity/php-baseline.json` remains an immutable
291291
2.5.13 / Workflow 2.5.4 reference, together with its known NUL reproducer outside

‎scripts/conformance/server-parity/native-image-corpus.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ scope="dw-parity-${GITHUB_RUN_ID:-local}-${GITHUB_RUN_ATTEMPT:-1}-${GITHUB_JOB:-
2727
export RESOURCE_SCOPE="$scope"
2828
export DW_PARITY_RUNNER_REVISION
2929
DW_PARITY_RUNNER_REVISION=$(git rev-parse HEAD)
30-
image=$(jq -r '.server.images["linux/amd64"] | sub("^durableworkflow/server@"; "ghcr.io/durable-workflow/server@")' tests/Fixtures/ServerParityBaselines/php-2.11.5.json)
30+
image=$(jq -r '.server.images["linux/amd64"] | sub("^durableworkflow/server@"; "ghcr.io/durable-workflow/server@")' tests/Fixtures/ServerParityBaselines/php-2.11.7.json)
3131

3232
# CI's corpus selection: the reviewed corpus without service-calls, which
3333
# records separately below with PHP's maintenance loop stopped (Server #796),

‎scripts/conformance/server-parity/role-profile.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ test -n "$RESOURCE_SCOPE"
88
scope_identity="$GITHUB_RUN_ID-$GITHUB_RUN_ATTEMPT-$GITHUB_JOB"
99
case "$RESOURCE_SCOPE" in *"$scope_identity"*) ;; *) exit 2 ;; esac
1010
backend="$1"
11-
image=$(jq -r '.server.images["linux/amd64"] | sub("^durableworkflow/server@"; "ghcr.io/durable-workflow/server@")' tests/Fixtures/ServerParityBaselines/php-2.11.5.json)
11+
image=$(jq -r '.server.images["linux/amd64"] | sub("^durableworkflow/server@"; "ghcr.io/durable-workflow/server@")' tests/Fixtures/ServerParityBaselines/php-2.11.7.json)
1212
rust_image=mirror.gcr.io/library/rust@sha256:ba81bc3eaa4422af576c0262515d96b0111a628a6ccc2c86557cf55c9a4bbee0
1313
fixture=tests/Fixtures/ServerParityProfiles/role-tokens/admission-role-tokens.json
1414
credentials=(-e DW_AUTH_TOKEN=parity-role-legacy -e DW_WORKER_TOKEN=parity-role-worker

‎scripts/conformance/server-parity/update-validation-sqlite.sh‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ name="${3:-update-validation}"
3737
[[ -n "$DW_PARITY_RUNNER_REVISION" ]]
3838
fixture="tests/Fixtures/ServerParity/$name.json"
3939
test -f "$fixture"
40-
image=$(jq -r '.server.images["linux/amd64"] | sub("^durableworkflow/server@"; "ghcr.io/durable-workflow/server@")' tests/Fixtures/ServerParityBaselines/php-2.11.5.json)
40+
image=$(jq -r '.server.images["linux/amd64"] | sub("^durableworkflow/server@"; "ghcr.io/durable-workflow/server@")' tests/Fixtures/ServerParityBaselines/php-2.11.7.json)
4141
. scripts/conformance/server-parity/php-maintenance-window.sh
4242

4343
prefix=parity-v1

0 commit comments

Comments
 (0)