event

package
v0.38.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 11, 2026 License: Apache-2.0 Imports: 29 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (

	// ErrOutboxSinkRouteMismatch indicates a routing rule references the
	// outbox transport but excludes the configured outbox.sink from its
	// subscribable transports. Subscribers attached via such a route
	// would silently miss every event: the bus filters them onto the
	// route's non publish-only transports while the outbox relay
	// dispatches into the (unrelated) sink. The check runs once during
	// fx Start so misconfigurations fail loudly instead of producing a
	// silent broken pipe at runtime.
	ErrOutboxSinkRouteMismatch = errors.New("event outbox: sink missing from outbox-bearing route")
)
View Source
var InboxModule = fx.Module(
	"vef:event:inbox",
	fx.Provide(
		fx.Annotate(
			newInboxRepository,
			fx.As(fx.Self()),
			fx.As(new(inbox.Repository)),
		),
		fx.Annotate(
			newInboxMiddleware,
			fx.ResultTags(`group:"vef:event:consume-middlewares"`),
			fx.As(new(middleware.ConsumeMiddleware)),
		),
	),
	fx.Invoke(runInboxMigration),
	fx.Invoke(registerInboxCleanup),
)

InboxModule wires the sys_event_inbox repository, runs its migration, schedules retention cleanup, and contributes the Inbox consume middleware. The middleware only activates on transports that declare AtLeastOnce semantics so in-process delivery stays cheap.

View Source
var Module = fx.Module(
	"vef:event",
	fx.Provide(
		fx.Annotate(
			newMemoryTransport,
			fx.ResultTags(`group:"vef:event:transports"`),
			fx.As(new(transport.Transport)),
		),
		defaultErrorSink,
		defaultMetricsRecorder,

		fx.Annotate(
			newRecoverMiddleware,
			fx.ResultTags(`group:"vef:event:consume-middlewares"`),
			fx.As(new(middleware.ConsumeMiddleware)),
		),
		fx.Annotate(
			newLoggingPublishMiddleware,
			fx.ResultTags(`group:"vef:event:publish-middlewares"`),
			fx.As(new(middleware.PublishMiddleware)),
		),
		fx.Annotate(
			newLoggingConsumeMiddleware,
			fx.ResultTags(`group:"vef:event:consume-middlewares"`),
			fx.As(new(middleware.ConsumeMiddleware)),
		),
		fx.Annotate(
			newTracingPublishMiddleware,
			fx.ResultTags(`group:"vef:event:publish-middlewares"`),
			fx.As(new(middleware.PublishMiddleware)),
		),
		fx.Annotate(
			newTracingConsumeMiddleware,
			fx.ResultTags(`group:"vef:event:consume-middlewares"`),
			fx.As(new(middleware.ConsumeMiddleware)),
		),
		fx.Annotate(
			newMetricsPublishMiddleware,
			fx.ResultTags(`group:"vef:event:publish-middlewares"`),
			fx.As(new(middleware.PublishMiddleware)),
		),
		fx.Annotate(
			newMetricsConsumeMiddleware,
			fx.ResultTags(`group:"vef:event:consume-middlewares"`),
			fx.As(new(middleware.ConsumeMiddleware)),
		),
		fx.Annotate(
			newBus,
			fx.ParamTags(
				``,
				``,
				`group:"vef:event:transports"`,
				`group:"vef:event:publish-middlewares"`,
				`group:"vef:event:consume-middlewares"`,
				``,
				``,
			),
			fx.As(fx.Self()),
			fx.As(new(event.Bus)),
			fx.As(new(event.RouteInspector)),
		),
	),
)

Module wires the Bus, registers the always-on memory transport, and exposes fx groups for downstream modules (outbox, redis_stream, inbox) to plug additional transports and middleware.

View Source
var OutboxModule = fx.Module(
	"vef:event:outbox",
	fx.Provide(
		fx.Annotate(
			newOutboxRepository,
			fx.As(fx.Self()),
			fx.As(new(outbox.Repository)),
		),

		fx.Annotate(
			newOutboxTransport,
			fx.ResultTags(`group:"vef:event:transports"`),
			fx.As(new(transport.Transport)),
		),
	),
	fx.Invoke(runOutboxMigration),
	fx.Invoke(registerOutboxCleanup),
	fx.Invoke(
		fx.Annotate(
			bindOutboxSinkAndRelay,
			fx.ParamTags(``, ``, ``, `group:"vef:event:transports"`),
		),
	),
)

OutboxModule wires the outbox transport, its repository, the database migration, and the relay cron job. Sink binding is deferred until after the transport registry is fully populated to avoid a circular fx dependency.

All components are gated by vef.event.transports.outbox.enabled — when disabled, no Transport is contributed to the registry and the relay cron job is not registered.

View Source
var RedisStreamTransportModule = fx.Module(
	"vef:event:redis_stream",
	fx.Provide(
		fx.Annotate(
			newRedisStreamTransport,
			fx.ParamTags(``, `optional:"true"`),
			fx.ResultTags(`group:"vef:event:transports"`),
			fx.As(new(transport.Transport)),
		),
		fx.Annotate(
			newRedisStreamInspector,
			fx.ParamTags(``, `optional:"true"`),
		),
	),
)

RedisStreamTransportModule wires the cross-process Redis Streams transport. Disabled by default; enable via vef.event.transports.redis_stream.enabled = true.

The *redis.Client dependency is optional so fx does not force the redis module to construct (and connect) when the transport is off — applications without redis configured can leave the module loaded without paying the connection penalty.

Functions

This section is empty.

Types

type Bus added in v0.24.0

type Bus struct {
	// contains filtered or unexported fields
}

Bus is the framework's event Bus implementation. It wires routing, per-transport delivery, async fan-in, and middleware composition.

started / stopped are atomic so the publish hot path can check the lifecycle state without taking b.mu. The mutex remains the authoritative serialiser for state transitions (Start / Stop) and for protecting the mutable pending / active maps.

func NewBus added in v0.24.0

func NewBus(
	cfg *config.EventConfig,
	appName string,
	transports []transport.Transport,
	publishMW []middleware.PublishMiddleware,
	consumeMW []middleware.ConsumeMiddleware,
	sink event.ErrorSink,
) *Bus

NewBus constructs a Bus from the supplied configuration, transport registry, and middleware groups. Subscribe calls are accepted before Start; they are flushed during Start once the router is resolved.

func (*Bus) HasSubscribableTransport added in v0.25.0

func (b *Bus) HasSubscribableTransport(eventType string) bool

HasSubscribableTransport implements event.RouteInspector. Returns false before Start (no router built yet) or when every transport resolving eventType is publish-only — in that case no Subscribe call against the route could ever succeed, so callers should fail fast.

func (*Bus) HasTransactionalRoute added in v0.24.0

func (b *Bus) HasTransactionalRoute(eventType string) bool

HasTransactionalRoute implements event.RouteInspector. Returns false before Start (no router built yet) or when no transactional transport is among the resolved route for eventType.

func (*Bus) Publish added in v0.24.0

func (b *Bus) Publish(ctx context.Context, evt event.Event, opts ...event.PublishOption) error

Publish implements event.Bus.

func (*Bus) PublishBatch added in v0.24.0

func (b *Bus) PublishBatch(ctx context.Context, evts []event.Event, opts ...event.PublishOption) error

PublishBatch implements event.Bus.

func (*Bus) Start added in v0.24.0

func (b *Bus) Start(ctx context.Context) error

Start hooks the bus into the fx lifecycle. It resolves the router, starts every transport, flushes pending subscriptions, then begins the async worker pool. If any transport fails to Start, all previously-started transports are Stopped so the bus does not leak goroutines.

func (*Bus) Stop added in v0.24.0

func (b *Bus) Stop(ctx context.Context) error

Stop drains async work, unsubscribes all active subscriptions, and stops every transport. Idempotent; no-ops if Start never completed.

func (*Bus) Subscribe added in v0.24.0

func (b *Bus) Subscribe(eventType string, h event.Handler, opts ...event.SubscribeOption) (event.Unsubscribe, error)

Subscribe implements event.Bus. When called before Start the registration is buffered; the returned Unsubscribe cancels the pending registration. After Start the call attaches handlers to all matched transports.

Directories

Path Synopsis
transport

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL