Releases: tmaxmax/go-sse
v0.8.0
This version removes all external dependencies of go-sse
. All our bugs are belong to us! It also does some API and documentation cleanups.
Removed
Client.DefautReconnectionTime
,Client.MaxRetries
have been replaced with the newClient.Backoff
configuration field. See the Added section for more info.ErrReplayFailed
is removed from the public API.ReplayProviderWithGC
andJoe.ReplayGCInterval
are no more. The responsibility for garbage collection is assigned to the replay providers.
Changed
Server.Logger
is now of a new type: theLogger
interface. The dependency on x/exp/slog is removed. This opens up the possibility to adapt any existing logger to be usable withServer
.- The default backoff behavior has changed. The previous defaults map to the new
Backoff
configuration as follows:
sse.Backoff{
InitialInterval: 5 * time.Second, // currently 500ms
Multiplier: 1.5, // currently the same
Jitter: 0.5, // currently the same
MaxInterval: 60 * time.Second, // currently unbounded
MaxElapsedDuration: 15 * time.Minute, // currently unbounded
MaxRetries: -1, // previously no retries by default, currently unbounded
}
Joe
now accepts new subscriptions even if replay providers panic (previouslyErrReplayFailed
would be returned).Server.ServeHTTP
panics if a customOnSession
handler returns aSubscription
with 0 topics
Added
- The
Logger
interface,LogLevel
type, andLogLevel(Info|Warn|Error)
values. Backoff
andClient.Backoff
– the backoff strategy is now fully configurable. See the code documentation for info.ValidReplayProvider.GCInterval
, to configure at which interval expired events should be cleaned up.
v0.7.0
This version overhauls connection retry and fixes the connection event dispatch order issue. Some internal changes to Joe were also made, which makes it faster and more resilient.
Removed
ConnectionError.Temporary
ConnectionError.Timeout
Changed
- Go's
Timeout
andTemporary
interfaces are not used anymore – the client makes no assumptions and retries on every network or response read error. The only cases whenConnection.Connect
returns now are either when there are no more retries left (when the number is not infinite), or when the request context was cancelled. *url.Error
s that occur on the HTTP request are now unwrapped and their cause is put inside aConnectionError
.Connection.Connect
doesn't suppress any errors anymore: the request context errors are returned as is, all other errors are wrapped insideConnectionError
.- On reconnection attempt, the response reset error is now wrapped inside
ConnectionError
. With this change, all errors other than the context errors are wrapped insideConnectionError
. - Subscription callbacks are no longer called in individual goroutines. This caused messages to be received in an indereminate order. Make sure that your callbacks do not block for too long!
- If a
ReplayProvider
method panics when called byJoe
, instead of closing itself completely it just stops replaying, putting or GC-ing messages to upcoming clients.Joe
continues to function as if no replay provider was given. A stack trace is printed to stderr when such a panic occurs.
v0.6.0
This version brings a number of refactors to the server-side tooling the library offers. Constructors and construction related types are removed, for ease of use and reduced API size, concerns regarding topics and expiry were separated from Message
, logging of the Server
is upgraded to structured logging and messages can be now published to multiple topics at once. Request upgrading has also been refactored to provide a more functional API, and the Server
logic can now be customized without having to create a distinct handler.
Removed
Message.ExpiresAt
is no more.Message.Topic
is no more. See the changes toServer
,Provider
andReplayProvider
for handling topics – you can now publish a message to multiple topics at once.Message.Writer
is no more. The API was redundant – one can achieve the same usingstrings.Builder
andMessage.AppendData
. See theMessageWriter
example for more.NewValidReplayProvider
is no more.NewFiniteReplayProvider
is no more.NewJoe
is no more.JoeConfig
is no more.Server.Subscribe
is no more – it never made sense.Server.Provider
is no more.NewServer
,ServerOption
and friends are no more.- The
Logger
interface and the capability of theServer
to use types that implementLogger
as logging systems is removed. SubscriptionCallback
is no more (see the change to theSubscription
type in the "Changed" section).
Added
- Because the
ValidReplayProvider
constructor was removed, the fieldsValidReplayProvider.{TTL,AutoIDs}
were added for configuration. - Because the
FiniteReplayProvider
constructor was removed, the fieldsFiniteReplayProvider.{Count,AutoIDs}
were added for configuration. - Because the
Joe
constructor was removed, the fieldsJoe.{ReplayProvider,ReplayGCInterval}
were added for configuration. - Because the
Server
constructor was removed, the fieldServer.Provider
was added for configuration. - New
MessageWriter
interface; used by providers to send messages and implemented bySession
(previously namedRequest
). - New
ResponseWriter
interface, which is ahttp.ResponseWriter
augmented with aFlush
method. ValidReplayProvider
has a new fieldNow
which allows providing a custom current time getter, liketime.Now
, to the provider. Enables deterministic testing of dependents onValidReplayProvider
.- New
Server.OnSession
field, which enables customization ofServer
's response and subscriptions. - New
Server.Logger
field, which enables structured logging with logger retrieved from the request and customizable config of logged information.
Changed
ReplayProvider.Put
takes a simple*Message
and returns a*Message
, instead of changing the*Message
to which the**Message
parameter points.
It also takes a slice of topics, given that theMessage
doesn't hold the topic itself anymore. If the Message cannot be put, the method must now panic – see documentation for info.- Because
Message.ExpiresAt
is removed, theValidReplayProvider
sets the expiry itself. Server.Publish
now takes a list of topics.Provider.Publish
now takes a non-empty slice of topics.ReplayProvider.Put
now takes a non-empty slice of topics.Provider.Stop
is nowProvider.Shutdown
and takes now acontext.Context
as a parameter.Server.Shutdown
takes now acontext.Context
as a parameter.Request
is now namedSession
and exposes the HTTP request, response writer, and the last event ID of the request.- A new method
Flush
is added toSession
; messages are no longer flushed by default, which allows providers, replay providers to batch send messages. Upgrade
now takes an*http.Request
as its second parameter.Subscription
now has aClient
field of typeMessageWriter
instead of aCallback
.- Given the
Subscription
change,Provider.Subscribe
andReplayProvider.Replay
now report message sending errors.
If you have any suggestions, things are breaking, need some help or want to show appreciation, please and feel free to open an issue, say somthing in the Discussion of this release, or text me in private using the socials on my profile!
v0.5.2
Added
- The new
Message.Writer
– write to theMessage
as if it is anio.Writer
.
Fixed
Message.UnmarshalText
now strips the leading Unicode BOM, if it exists, as per the specification.- When parsing events client-side, BOM removal was attempted on each event input. Now the BOM is correctly removed only when parsing is started.
v0.5.1
Fixed
Message.WriteTo
now writes nothing ifMessage
is empty.Message.WriteTo
does not attempt to write theretry
field ifMessage.Retry
is not at least 1ms.NewType
error message is updated to say "event type", not "event name".
If you have any suggestions, things are breaking, need some help or want to show appreciation, please and feel free to open an issue or text me in private using the socials on my profile!
v0.5.0
This version comes with a series of internal refactorings that improve code readability and performance. It also replaces usage of []byte
for event data with string
– SSE is a UTF-8 encoded text-based protocol, so raw bytes never made sense. This migration improves code safety (less unsafe
usage and less worry about ownership) and reduces the memory footprint of some objects.
Creating events on the server is also revised – fields that required getters and setters, apart from data
and comments, are now simple public fields on the sse.Message
struct.
Across the codebase, to refer to the value of the event
field the name "event type" is used, which is the nomenclature used in the SSE specification.
Documentation and examples were also fixed and improved.
Added
- New
sse.EventName
type, which holds valid values for theevent
field, together with constructors (sse.Name
andsse.NewName
).
Removed
sse.Message
:AppendText
was removed, as part of the migration from byte slices to strings. SSE is a UTF-8 encoded text-based protocol – raw bytes never made sense.
Changed
- Minimum supported Go version was bumped from 1.16 to 1.19. From now on, the latest two major Go versions will be supported.
sse.Message
:AppendData
takesstring
s instead of[]byte
.sse.Message
:Comment
is now namedAppendComment
, for consistency withAppendData
.sse.Message
: The message's expiration is not reset anymore byUnmarshalText
.sse.Message
:UnmarshalText
now unmarshals comments aswell.sse.Message
:WriteTo
(andMarshalText
andString
as a result) replaces all newline sequences in data with LF.sse.Message
: TheExpiry
getter andSetExpiresAt
,SetTTL
setters are replaced by the public fieldExpiresAt
.sse.Message
: Event ID getter and setter are replaced by the publicID
field.sse.Message
: Event type (previously namedName
) getter and setter are replaced by the publicType
field.sse.Message
: Theretry
field value is now a public field on the struct. As a byproduct,WriteTo
will now make 1 allocation when writing events with theretry
field set.sse.NewEventID
is nowsse.NewID
, andsse.MustEventID
issse.ID
.sse.Event
: TheData
field is now of typestring
, not[]byte
.sse.Event
: TheName
field is now namedType
.
Fixed
sse.Message
:Clone
now copies the topic of the message to the new value.sse.Message
: ID fields that contain NUL characters are now ignored, as required by the spec, inUnmarshalText
.
If you have any suggestions, things are breaking, need some help or want to show appreciation, please and feel free to open an issue or text me in private using the socials on my profile!