fix(channel): flip S1 S4 S5 S7 S8 and fix S9 drain - #3418
Merged
Conversation
Failing specs for the five Peter flips (S1 publish throw, S4 unknown adapter, S5 memory lastEventId replay, S7 named-event listeners, S8 empty name). Prove-current specs for S2/S3/S6 swallows. S9 drain regression and S10 assertion tightening. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Peter Amiri <peter@alurium.com>
Publish INSERT failures throw Wheels.Channel.PublishFailed. Unknown adapters throw Wheels.Channel.UnknownAdapter. Memory Channel.replay() feeds lastEventId on subscribe. channelSSETag registers addEventListener for named events. Empty channel names throw Wheels.Channel.InvalidName. $drainChannelBuffer removes items instead of clear(). Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Peter Amiri <peter@alurium.com>
ArrayList.remove(0) bound to remove(Object) and returned false, so replayed events never reached the SSE writer. poll() drains the queue without dropping mid-loop publishes. Signed-off-by: Cursor Agent <cursoragent@cursor.com> Co-authored-by: Peter Amiri <peter@alurium.com>
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.
Why
Peter flipped all five Channel holds. Publish errors, unknown adapters, and empty names failed open. Memory lastEventId never replayed.
channelSSETagwas onmessage-only, so named events never reached the page. Memory drainclear()could drop events published mid-loop.This PR flips S1, S4, S5, S7, and S8, proves S2/S3/S6 as they stand, fixes S9, and tightens S10. Desk IDs stay S1–S10.
LuCLI run 32846469178 failed on
d06dc15dwith HTTP 417 (5206/0/1). The one error was S5$subscribeMemory sends replayed events and not the lastEventId itselfreadingsent[1].dataon a boolean. MockBox$()ofsendSSEEventlogs a boolean, not the event struct.1880df1dalready dropped that$callLog().sendSSEEvent[n].dataread. The spec now asserts the SSE writer body (id: s5-new,data: new, noid: s5-old) plusengine.replay()unit pins for events after lastEventId, never the lastEventId itself.The
$getChannelEngineleftover insubscribeToChannel's else-branch stays closed. Not S11.subscribeToChannel(adapter="redis")still takes memory.Scope
vendor/wheels/Channel.cfc— bounded event log,replay(), empty-name throwvendor/wheels/channel/DatabaseAdapter.cfc—PublishFailedon INSERT fail, empty-name throwvendor/wheels/global/routing.cfm—UnknownAdapterfor names that are notmemoryordatabasevendor/wheels/controller/channels.cfc— named-eventaddEventListener, lastEventId replay,$drainChannelBufferviaConcurrentLinkedQueue.poll(), empty-name throwvendor/wheels/tests/specs/channel/ChannelHardenerSpec.cfcvendor/wheels/tests/specs/channel/DatabaseAdapterSpec.cfcvendor/wheels/tests/specs/controller/channelSpec.cfcvendor/wheels/tests/_assets/channel/BrokenDatasourceAdapter.cfcvendor/wheels/tests/_assets/channel/MidLoopPublishBuffer.cfcvendor/wheels/tests/_assets/channel/SseWriterFake.cfcchangelog.d/channel-hardener-s1-s8.changed.mdchangelog.d/channel-hardener-s9.fixed.mdOut: CLI
ReleaseChannel, docs/blog, SQLdatabaseAdapters, leftover$getChannelEnginesilent-memory insubscribeToChannel.Tradeoffs
Typed
Wheels.Channel.*errors instead of raw engine exceptions. Duplicate-key and missing-table INSERT failures both becomePublishFailed.Memory replay is a bounded in-process log on
Channel.cfc. It is not durable across restart. That is the memory adapter.S5 subscribe no longer mocks
sendSSEEvent. A realSseWriterFakerecordswrite()bytes so the spec canFind("id: s5-new")without touching MockBox call-log booleans.Blast Radius
publish()with a failed INSERT now throws. Callers that readpersistedand continued will see the throw.$getChannelEngine("redis")throws.publish(adapter="redis")throws with it.subscribeToChannel(adapter="redis")still takes the memory branch. That leftover stays closed.Empty and whitespace-only channel names throw on publish, subscribe,
subscribeToChannel, andchannelSSETag.Desk S1–S10
Wheels.Channel.PublishFailed. Source pin. Nopersisted:false.cleanup()returns 0 and does not throw. Catch-any fail-open kept.$ensureEventsTable()returns false and does not throw.$getChannelEngine("redis")and"memeory"throwWheels.Channel.UnknownAdapter.memoryanddatabasestill resolve.engine.replay()returns events after lastEventId.$subscribeMemorywritesid: s5-new/data: newthroughSseWriterFake.Find("id: s5-old")is 0.1880df1ddropped$callLog().sendSSEEvent[n].data.lastEventIdstill reaches the memory loop.GetHTTPRequestDatacatch-any kept.channelSSETag(events="notification,alert")emitsaddEventListenerfor both names and keepssrc.onmessage.Wheels.Channel.InvalidNameon publish, subscribe,subscribeToChannel, andchannelSSETag.$drainChannelBufferkeeps a mid-loop publish.$subscribeMemorydoes not callclear().channelSSETagemits EventSource. Poll counts are exact on unique channels.Verification
Commands actually run:
Scope:
wheels.tests.specs.channelRed (LuCLI 32846469178 on
d06dc15d): HTTP 417, Results 5206/0/1. The S5 subscribe spec read$callLog().sendSSEEvent[1].dataon a boolean.Green (LuCLI 32847005260 on
1880df1d): Results 5207 passed, 0 failed, 0 errors. The one S5 error is now a pass.Local driver on this HEAD:
JSON from the same filter (
directory=wheels.tests.specs.channel):Wheels CLI 4.0.6. Lucee 7.0.0.395. sqlite.
Adobe and BoxLang were not run here.
HEAD
1880df1d179eb496a89409df6e374f133ff81032Base
b8065e3a8ee7b90c2374cd9f16d8bcfd010026e2(develop after #3417).No closer keywords. Do not merge.