Documentation
¶
Overview ¶
Package source defines where an event stream's events come from, the contract by which a source delivers them, and the gRPC service that provides a source's event streams to remote engines.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrConsumerTooSlow is the error that [Source.Watch] returns when its // caller can not keep up, so that a stream can no longer be delivered // contiguously. ErrConsumerTooSlow = errors.New("consumer is too slow") // ErrUnrecognizedStream is the error that [Source.Read] returns for a // stream that the source does not have. ErrUnrecognizedStream = errors.New("event stream is not recognized") // ErrOffsetOutOfRange is the error that [Source.Read] returns when the // given offset is beyond the end of the stream. ErrOffsetOutOfRange = errors.New("offset is beyond the end of the event stream") // ErrInvalidSegment is the error that [Remote] returns when the remote // engine sends a segment that is malformed, that holds events of types // that were not requested, or that does not begin where the previous // segment of its stream ended. ErrInvalidSegment = errors.New("invalid segment") )
Functions ¶
This section is empty.
Types ¶
type Local ¶
type Local struct {
// DB is the database connection used to discover event streams and read
// events.
DB *sql.DB
// Signals is the bus used to receive signals that event streams have been
// created and that events have been appended to them.
Signals *signal.Bus
// Logger is the target for log messages produced by the source.
Logger *slog.Logger
// SegmentSize is the maximum number of events delivered in one segment,
// which is also the number of events read per query. It must be positive.
SegmentSize int
// BufferSize is the number of segments buffered for each call to
// [Local.Watch]. A call that falls further behind than this ends with an
// error that wraps [ErrConsumerTooSlow]. It must be positive.
BufferSize int
// contains filtered or unexported fields
}
Local is a Source of the event streams in this application's database.
Local.Run follows each stream once, however many calls to Local.Watch are in progress, and delivers each segment that it loads to every one of those calls.
func (*Local) Read ¶
func (s *Local) Read( ctx context.Context, streamID *uuidpb.UUID, types *uuidcollection.Set, begin uint64, fn func(Segment) error, ) error
Read delivers events from a stream to fn, beginning at the given offset.
func (*Local) Run ¶
Run watches the application's streams on behalf of every call to Local.Watch, until ctx is canceled.
It must be called at most once. Local.Watch may be called before it, and the call is served once it begins.
func (*Local) Watch ¶
func (s *Local) Watch( ctx context.Context, types *uuidcollection.Set, fn func(Segment) error, ) error
Watch delivers events to fn as they are appended to the application's streams.
Each stream is delivered from its end, as it stands when the call begins or when the stream is discovered. It returns an error that wraps ErrConsumerTooSlow if fn falls more than Local.BufferSize segments behind, and another error if any stream can not be delivered any further. The call is served by Local.Run.
type Memory ¶
type Memory struct {
// SegmentSize is the maximum number of events delivered in one segment by
// Read. Zero means no limit.
SegmentSize int
// contains filtered or unexported fields
}
Memory is a Source that holds its streams in memory.
func (*Memory) Append ¶
Append appends a segment to the stream it belongs to, creating the stream if it is the first segment. The segment must begin where the stream ends.
type Remote ¶
type Remote struct {
// Client is the client used to call the remote engine's event stream
// consumer API.
Client messaginggrpc.EventStreamConsumerAPIClient
}
Remote is a Source of the event streams of an application hosted by a remote engine, consumed via its messaginggrpc.EventStreamConsumerAPI service.
Each segment that the remote engine sends is checked before it is delivered. If a segment is malformed, holds events of types that were not requested, or does not begin where the previous segment of its stream ended, Remote.Watch or Remote.Read returns an error that wraps ErrInvalidSegment instead of delivering it.
func (*Remote) Read ¶
func (s *Remote) Read( ctx context.Context, streamID *uuidpb.UUID, types *uuidcollection.Set, begin uint64, fn func(Segment) error, ) error
Read delivers events from a stream to fn, beginning at the given offset.
func (*Remote) Watch ¶
func (s *Remote) Watch( ctx context.Context, types *uuidcollection.Set, fn func(Segment) error, ) error
Watch delivers events to fn as they are appended to the remote application's streams.
Each stream's opening segment begins wherever the remote engine begins it. The remote engine never ends the watch of its own accord, so it ending is a failure.
type Segment ¶
type Segment struct {
// StreamID is the ID of the event stream that this is a segment of.
StreamID *uuidpb.UUID
// Begin and End bound the segment, [Begin, End).
Begin, End uint64
// Envelopes are the events in the segment that match the message types for
// which it was read, in offset order.
//
// It may be empty, indicating only that the range holds no events of those
// types.
//
// Each envelope has the [envelopepb.EventStreamPosition] extension set.
Envelopes []*envelopepb.Envelope
}
Segment is a contiguous piece of one event stream, the half-open range [Begin, End), carrying the events in that range that match a set of message types.
type Server ¶
type Server struct {
// EventStreams is the source of the event streams that the server
// provides.
EventStreams Source
// MaxSegmentBytes is the maximum combined size, in bytes, of the events in
// each segment that the server sends. A segment whose events are larger is
// sent as several contiguous segments. If a single event is larger than
// this, it is sent on its own. It must be positive.
MaxSegmentBytes int
}
Server provides the messaginggrpc.EventStreamConsumerAPI service over the event streams of a Source, so that remote engines can consume them.
func (*Server) ReadEvents ¶
func (s *Server) ReadEvents( req *messaginggrpc.ReadEventsRequest, res grpc.ServerStreamingServer[messaginggrpc.EventStreamSegment], ) error
ReadEvents implements the ReadEvents method of messaginggrpc.EventStreamConsumerAPIServer.
func (*Server) WatchEvents ¶
func (s *Server) WatchEvents( req *messaginggrpc.WatchEventsRequest, res grpc.ServerStreamingServer[messaginggrpc.EventStreamSegment], ) error
WatchEvents implements the WatchEvents method of messaginggrpc.EventStreamConsumerAPIServer.
type Source ¶
type Source interface {
// Watch delivers events to fn as they are appended to the source's
// streams.
//
// Only events of the given types are delivered. A nil set of types means
// events of every type. It panics if the set is empty.
//
// The first segment of a stream that a call delivers is called the stream's
// opening segment. It begins at the stream's end, and may be empty. Every
// later segment of the stream begins where the previous one ended, for as
// long as the call lasts. The opening segment of a later call may begin
// after events that this call never delivered; a caller that needs them
// reads them with [Source.Read].
//
// fn may be called concurrently for different streams, but a stream's
// segments are delivered one at a time, in order.
//
// It blocks until ctx is canceled or it is unable to continue, and may be
// called again once it returns. It returns fn's error, unchanged, if fn
// returns one, and an error that wraps [ErrConsumerTooSlow] if the caller
// can not keep up.
Watch(
ctx context.Context,
types *uuidcollection.Set,
fn func(Segment) error,
) error
// Read delivers events from a stream to fn, beginning at the given
// offset.
//
// Only events of the given types are delivered, in contiguous segments,
// until the end of the stream as it stands, at which point it returns
// nil. A nil set of types means events of every type. It panics if the
// set is empty.
//
// It delivers nothing from an offset at the end of the stream. It returns
// an error that wraps [ErrOffsetOutOfRange] for an offset beyond the end,
// one that wraps [ErrUnrecognizedStream] for a stream that the source does
// not have, and fn's error, unchanged, if fn returns one.
Read(
ctx context.Context,
streamID *uuidpb.UUID,
types *uuidcollection.Set,
begin uint64,
fn func(Segment) error,
) error
}
Source is where an event stream's events come from: this application's database, or a remote engine.