github nats-io/nats.go v1.55.0
Release v1.55.0

3 hours ago

Changelog

This is the biggest nats.go release in a long time: 47 changes with more than half of them coming from 18 external contributors - thank you all!

Most of this release is a robustness effort. Nearly 30 bug fixes address deadlocks, goroutine and timer leaks, data races and stalls in reconnect and drain handling, pull and ordered consumers, async publish and service API. It also adds the FetchMaxBytes() option and Conn.RemoteAccount().

ADDED

  • Core NATS:
    • Conn.RemoteAccount() and ServerInfo.RemoteAccount exposing the account the client is bound to (#2156)
  • JetStream:
    • FetchMaxBytes() option to limit both the number of messages and total bytes in a single Fetch() request. Thanks @manenim for the contribution (#2198)
    • StreamInfo.Domain, StreamInfo.Alternates, StreamState.Lost, StreamSourceInfo.External and StreamSourceInfo.Error in stream info (#2168)
    • ErrStreamMessageExceedsMaximum for JetStream error code 10054, returned when a message exceeds the stream's MaxMsgSize. Thanks @matehsan for the contribution (#2110)

FIXED

  • Core NATS:
    • ForceReconnect() called while already reconnecting disabling ReconnectWait and custom reconnect delays, so the client dialed in a tight loop. Thanks @Arsen302 for the contribution and @MokiMeow for the diagnosis and test (#2179)
    • Connection closing for good instead of reconnecting after a partial write left a truncated message on the wire (#2169)
    • Connection status listeners losing an unread event and being unregistered when the next status was sent (#2193)
    • Message headers not counted against subscription pending byte limits, so header-heavy subscriptions could exceed the limit without reporting a slow consumer. Thanks @Grivn for the contribution (#2200)
    • Requests interrupted by a reconnect returning ErrConnectionClosed instead of ErrDisconnected. Thanks @AshSgDe29071999 for the contribution (#2129)
    • Default port added to the path instead of the host for server URLs with a path and no port, e.g. ws://host/nats. Thanks @dannyshafer for the contribution (#2177)
    • Close() during Drain() flipping the closed connection back to DRAINING_PUBS and flushing on it. Thanks @Kshot3000 for the contribution (#2163)
    • Drain() waiting for the full DrainTimeout when the connection was closed mid-drain (#2171)
    • IsSystemAccount() reset to false by async INFO updates, such as cluster topology changes or lame duck mode (#2156)
  • JetStream:
    • Pull consumer Consume() and Messages() deadlocking on Stop() or Drain() while buffered messages were still being delivered. Thanks @clwluvw for the contribution (#2165)
    • Messages() iterator goroutines leaking after the connection is closed. Thanks @clwluvw for the contribution (#2166)
    • Heartbeat timer and status listener left running when Consume() ends because the connection was closed. Thanks @clwluvw for the contribution (#2164)
    • Messages() iterator returning ErrMsgIteratorClosed instead of the remaining buffered messages when Next() raced with Drain() (#2188)
    • Pull consumer with StopAfter stalling until the missed heartbeat check (30s by default) after a pull expired. Thanks @huynguyen7 for the contribution (#2208)
    • Ordered consumer with StopAfter hanging on Stop()/Drain(), delivering too many or too few messages, or panicking after a consumer reset. Thanks @clwluvw for the contribution (#2167)
    • Ordered consumer Fetch(), Next() and FetchBytes() blocking forever after returning ErrOrderedConsumerConcurrentRequests, and FetchNoWait() restarting from the beginning of the stream (#2211)
    • Ordered consumer Consume() and Messages() using the 15s pull consumer heartbeat instead of the 5s ordered default, so a stalled consumer was reset after ~30s instead of ~10s. Thanks @arminazimi for the contribution (#2182)
    • PublishAsync() exceeding WithPublishAsyncMaxPending() under concurrent calls. Thanks @ShravanthReddy for the contribution (#2126)
    • Async publish error callbacks for messages pending during a reconnect delayed until the publisher shut down. Thanks @H-XX-D for the contribution (#2150)
    • Data race between Info() and CachedInfo() on streams and consumers. Thanks @vulragrag-star for the contribution (#2152)
    • Reusing the same KeyValueConfig.Sources for several KeyValue buckets carrying the first bucket's subject transform into the next ones, so their reads returned ErrKeyNotFound. Thanks @zhechen-cs for the contribution (#2190)
    • Object Store GetFile() leaving trailing bytes of an existing destination file when downloading a shorter object. Thanks @zhechen-cs for the contribution (#2197)
  • Legacy JetStream:
    • Async publish error callbacks for messages pending during a reconnect delayed until the publisher shut down. Thanks @H-XX-D for the contribution (#2150)
    • KeyValue Create() and Update() on a cross-domain mirrored bucket failing with nats: no response from stream. Thanks @spicysharkco for the contribution (#2203)
    • Object Store GetFile() leaving trailing bytes of an existing destination file when downloading a shorter object. Thanks @zhechen-cs for the contribution (#2197)
  • Service API:
    • Panic in AddService() on a closed connection (#2154)
    • Panic with send on closed channel when callbacks were queued during Stop() (#2173)
    • Service stopping on async errors from unrelated subscriptions with overlapping subjects. Async errors are now matched by subscription, recorded in endpoint stats and passed to ErrorHandler, and only a closed connection stops the service (#2174)
    • Stopping one service detaching the other services on the same connection from async errors and connection close (#2178)
    • Service and endpoint metadata changing after it was set, when the application modified the maps passed to or returned by the service (#2194)
    • Reset() clearing the endpoint queue group reported in stats (#2195)

IMPROVED

  • Core NATS:
    • Report Maximum Control Line Exceeded to the async error handler before closing the connection. Thanks @kave08 for the contribution (#2184)
    • Avoid extra allocations in DecodeHeadersMsg. Thanks @0xAozora for the contribution (#2132)
    • Compute header size in Msg.Size() without serializing headers. Thanks @0xAozora for the contribution (#2125)
    • Document that Subscription is safe for concurrent use and that Msg is not reused after delivery. Thanks @kave08 for the contributions (#2183, #2204)
  • JetStream:
    • Avoid heap allocation of publish options when publishing without options. Thanks @0xAozora for the contribution (#2124)
    • Avoid per-message metadata allocations in Fetch(), ordered consumers and Object Store Watch() (#2212)
  • Legacy JetStream:
    • Avoid per-message metadata allocations in Object Store Watch() (#2212)
    • Document the default MaxAckPending for subscriptions that create their own consumer (#2213)
  • Tests handle v2 ack subjects, which nats-server main now sends by default (#2192, #2186)
  • Fix ordered consumer test exceeding 1000 consumers (#2155) and bump the tester to fix intermittent server config parse errors (#2170)

Complete Changes

v1.54.0...v1.55.0

Don't miss a new nats.go release

NewReleases is sending notifications on new releases.