You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 3e737c5
Browse filesBrowse the repository at this point in the historyBrowse files
fix: gate Pulsar messages on bq-schema-version before decoding
PulsarTransport.pop rejects a delivery whose bq-schema-version property is present, not blank and
not the supported version, before the body is decoded (broker-bindings §5.7 step 3). Under
on_unknown_urn=RELEASE, gated, undecodable and URN-less messages now take the bounded FAIL path
instead of being released forever.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+23Lines changed: 23 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -28,6 +28,29 @@ The envelope wire format is versioned separately by `meta.schema_version`
28
28
stays on the poison / unknown-URN path instead of being routed to a handler.
29
29
30
30
### Fixed
31
+
-**`on_unknown_urn=RELEASE` no longer loops a version-gated or poison message forever.**
32
+
`BabelQueue.dispatch()` re-published such a message unchanged on every delivery (`attempts` never
33
+
grew, so it never reached the DLQ). A delivery a transport version-gated (reserved
34
+
`unsupported-schema-version``route_urn`, e.g. Pulsar `bq-schema-version`), an undecodable body
35
+
and a body naming no URN now take the bounded `FAIL` path under `RELEASE` (retry up to
36
+
`max_attempts`, then dead-letter or drop), matching the Go core (GR-5). A genuinely unknown URN
37
+
still releases verbatim. No public API or wire change. Note: as on the existing `FAIL` path, a
38
+
body that is not valid JSON is not carried verbatim through the retry / dead-letter re-publish
39
+
(the runtime re-encodes the envelope it could build, so the producer's original bytes are lost);
40
+
previously `RELEASE` re-published those bytes unchanged.
41
+
-**Pulsar consumer version-gates on `bq-schema-version` (broker-bindings §5.7 step 3).**
42
+
`PulsarTransport.pop()` now reads the `bq-schema-version` message property before decoding the
43
+
body. A missing or blank value changes nothing; "Blank" is the same set in every SDK: the empty string or only ASCII whitespace (space, `\t`, `\n`, `\v`, `\f`, `\r`); anything else (NBSP, U+001C-U+001F, U+0085, U+FEFF, U+3000, ...) is not blank and is rejected unless it is exactly the supported version. (`str.strip()` is not used: it also strips U+001C-U+001F, U+0085, NBSP, ...) a value other than the supported
44
+
`SCHEMA_VERSION` (`"2"`, `"x"`, `"01"`, ...) is not decoded: the delivery carries the reserved
45
+
`route_urn``babelqueue:unsupported-schema-version:<value>`, which no handler owns, so the
46
+
runtime quarantines it through the existing unknown-URN retry / dead-letter path (the error
47
+
names the rejected version). The body is passed through untouched. No wire change. The route
48
+
is an in-process marker only: it also carries the delivery's original `bq-job`, and the retry /
49
+
dead-letter re-publish (`publish_routed`) writes that original `bq-job` (or, when the delivery
50
+
had none, the body's job) and the original raw `bq-schema-version` back, never the sentinel, so
51
+
a redrive meets the same gate. The gate also logs a `babelqueue.pulsar` warning naming the
52
+
rejected version and queue, including for a body that is not valid JSON (which the runtime
53
+
quarantines as a poison message whose error names the reserved route).
31
54
-**Pulsar consumer now follows broker-bindings §5.2 / §5.7.**`PulsarTransport.pop()` routes on
32
55
the `bq-job` message property (set on `ReceivedMessage.route_urn`; the body's URN is used only
33
56
when the property is absent or blank) and takes `attempts` from the authoritative
0 commit comments