Skip to content

test: add concurrent publish/subscribe stress coverage for membus (#167) - #277

Merged
Jagadeeshftw merged 2 commits into
Grainlify:mainfrom
amankoli09:test/membus-concurrency-stress
Jul 27, 2026
Merged

test: add concurrent publish/subscribe stress coverage for membus (#167)#277
Jagadeeshftw merged 2 commits into
Grainlify:mainfrom
amankoli09:test/membus-concurrency-stress

Conversation

@amankoli09

Copy link
Copy Markdown
Contributor

Closes #167

📌 Description

This PR adds full thread-safe publish/subscribe capabilities to the in-memory bus implementation in

internal/bus/membus/membus.go
and introduces an extensive concurrent publish/subscribe stress test suite in

internal/bus/membus/membus_test.go
to ensure parity with natsbus under high concurrency.

🧩 Changes Implemented

Pub/Sub Parity in membus.go:

Added thread-safe Subscribe(subject string, handler func(Message)) (*Subscription, error) and Unsubscribe() error methods.
Designed fine-grained, deadlock-free synchronization where bus mutexes (b.mu) and subscription mutexes (s.mu) are never acquired out of order.
Subscriber handlers are invoked outside b.mu.Lock(), preventing deadlocks and simulating NATS decoupling where message publishing does not block on consumer callback execution.
Every subscriber handler receives a defensive copy of message payloads (Message.Data) to prevent concurrent slice mutations across overlapping subscribers.
Concurrency Stress Tests & Edge Case Coverage in membus_test.go:

TestConcurrentPublishSubscribe_NoMessageLoss: Spins up $N$ concurrent publishers and $M$ subscribers on shared topics; asserts exact message delivery counts across overlapping subscribers with zero dropped messages.
TestConcurrentPublishSubscribe_StressAndUnsubscribe: Stress test with 20 concurrent publishers and 15 concurrent subscribers repeatedly subscribing, receiving messages, and unsubscribing while publishes are actively in flight.
TestSubscriberUnsubscribeMidPublish: Explicitly verifies that calling sub.Unsubscribe() from within an active message callback mid-publish does not panic, deadlock, or affect other subscribers on the same topic.
TestPublishZeroSubscribers: Asserts that publishing to topics with zero subscribers correctly captures messages in bus history (b.Messages()) without errors or leaks.
TestManyTopicsOverlappingSubscribers: Validates exact message delivery across multiple overlapping subscribers listening to shared topics.
TestSubscriptionEdgeCases: Validates error handling (nil handler rejection, subscribing after bus Close(), zero-value bus initialization, and idempotent Unsubscribe()/Close() calls).

@Jagadeeshftw
Jagadeeshftw merged commit 3412e58 into Grainlify:main Jul 27, 2026
1 check failed
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.

Add concurrent publish/subscribe stress test for internal/bus/membus/membus.go

2 participants