Skip to content

docs(gochannel): GuaranteedOrder is not supported by default - #698

Open
baltasarblanco wants to merge 1 commit into
ThreeDotsLabs:masterfrom
baltasarblanco:gochannel-guaranteed-order-docs
Open

baltasarblanco wants to merge 1 commit into
ThreeDotsLabs:masterfrom
baltasarblanco:gochannel-guaranteed-order-docs

Conversation

@baltasarblanco

Copy link
Copy Markdown

Motivation / Background

The Go Channel characteristics table lists GuaranteedOrder | yes, but gochannel does not guarantee order with its default configuration, and the test suite has never claimed it did.

The table entry dates back to 043c41b (2019-07-07). The GuaranteedOrder flag was introduced into the gochannel tests a month later, in 577f2ac (2019-08-07), already set to false, and it has been false ever since — in pubsub_test.go and pubsub_stress_test.go alike. Because of that, the ordering assertions in pubsub/tests/test_pubsub.go (TestPublishSubscribe at line 410 and the consumer group test at line 538) have never run against gochannel.

Every other Pub/Sub in the docs matches its test suite on this flag — sql.md says yes and watermill-sql sets GuaranteedOrder: true in all six of its test invocations, for example. gochannel is the only one where the table and the tests disagree.

Refs #692.

Detail

Measured on v1.5.3, publishing 0..7 in order to a single subscriber, eight consecutive runs:

default                        -> [7 2 5 6 3 0 1 4]
default                        -> [3 1 7 4 2 5 6 0]
default                        -> [7 0 1 2 3 4 5 6]
default                        -> [7 0 1 2 3 4 5 6]
default                        -> [7 0 1 2 3 4 5 6]
default                        -> [0 3 4 5 7 1 6 2]
default                        -> [7 0 1 2 3 4 5 6]
default                        -> [7 2 6 3 1 5 4 0]

BlockPublishUntilSubscriberAck -> [0 1 2 3 4 5 6 7]
BlockPublishUntilSubscriberAck -> [0 1 2 3 4 5 6 7]
BlockPublishUntilSubscriberAck -> [0 1 2 3 4 5 6 7]

Out of order in every run with the default config. sendMessage (pubsub/gochannel/pubsub.go:164) spawns a goroutine per message per subscriber, so the order in which they reach s.sending is up to the scheduler.

BlockPublishUntilSubscriberAck makes Publish wait for each message to be acked before sending the next one, which preserves order as long as a single goroutine is publishing. With several publishing goroutines it reorders again. OutputChannelBuffer and Persistent make no difference either way.

This changes the table entry to no and adds a note describing the case where order is preserved, in the style of the existing kafka.md note about partition keys.

Alternative approaches considered (if applicable)

Making gochannel guarantee order by default would be the other way to resolve the mismatch, but that is a behaviour change rather than a documentation fix, and it would have to be reconciled with the test suite's current expectations. Happy to defer to you if that is the direction you'd prefer — in the meantime the table should describe what the implementation actually does.

Checklist

  • I wrote tests for the changes.
    • Not applicable: documentation-only change. The behaviour described is already what the existing test suite asserts via GuaranteedOrder: false.
  • All tests are passing.
    • make test_short and make test_race pass on this branch (Go 1.27.1, Linux amd64).
  • Code has no breaking changes.
  • (If applicable) documentation on watermill.io is updated.
    • This change is the documentation update.

The characteristics table has claimed GuaranteedOrder since 043c41b
(2019-07-07), but the test suite has declared GuaranteedOrder: false
for gochannel since the flag was introduced in 577f2ac (2019-08-07),
so the ordering assertions in pubsub/tests/test_pubsub.go have never
run against it.

sendMessage spawns a goroutine per message per subscriber, so the order
in which messages reach the subscriber is up to the scheduler. Publishing
0..7 in order to a single subscriber arrives out of order on every run.
Setting BlockPublishUntilSubscriberAck preserves order as long as a
single goroutine is publishing.

Refs ThreeDotsLabs#692
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant