scheduler()'s defer unconditionally calls close(b.data). If the channel
was closed by the caller (or an upstream producer) instead of via the
normal Close()-sends-nil path, the receive on b.data returns ok == false,
scheduler returns, and the deferred close(b.data) then fires on an
already-closed channel:
panic: close of closed channel
reliably reproducible under the #3653 steps (manually closing b.data
while Start() is running).
Track whether we observed the external-close via a local
`externallyClosed` flag set in the `ok == false` branch. The defer
only closes b.data when that flag is false, i.e. when the scheduler
exited through the nil-message or ticker paths and still owns the
channel. No behaviour change on the graceful Close() path.
Fixes#3653
* fix: performance issues with Kafka caused by encapsulating the MQ interface
* fix: admin token in standalone mode
* fix: full id version
* fix: resolve deadlock in cache eviction and improve GetBatch implementation
* refactor: replace LongConn with ClientConn interface and simplify message handling
* refactor: replace LongConn with ClientConn interface and simplify message handling
* fix: seq use $setOnInsert for min_seq in conversation update
* feat: add error code for handled friend requests and improve error handling in friend operations
* fix: performance issues with Kafka caused by encapsulating the MQ interface
* fix: admin token in standalone mode
* fix: full id version
* fix: resolve deadlock in cache eviction and improve GetBatch implementation
* refactor: replace LongConn with ClientConn interface and simplify message handling
* refactor: replace LongConn with ClientConn interface and simplify message handling
* fix: seq use $setOnInsert for min_seq in conversation update
* fix: performance issues with Kafka caused by encapsulating the MQ interface
* fix: admin token in standalone mode
* fix: full id version
* fix: resolve deadlock in cache eviction and improve GetBatch implementation
* refactor: replace LongConn with ClientConn interface and simplify message handling
* refactor: replace LongConn with ClientConn interface and simplify message handling
* fix: reset user conversation seq when rejoining group to resolve message recall issue
* fix: refactor setMemberJoinSeq based on review feedback
* group: 入群个人上限重置为不受限值;退出个人上限固化;通知控制入群 minSeq
* fix: performance issues with Kafka caused by encapsulating the MQ interface
* fix: admin token in standalone mode
* fix: full id version
* fix: resolve deadlock in cache eviction and improve GetBatch implementation
* feat: implement ratelimit and circuitbreaker in middleware.
* Build: Implement rate limiting and circuit breaker for API and RPC services.
* revert change.
* update ratelimiter and circuitbreaker config.
* update tools to openimsdk tools