feat: gamemaster
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
// Package notificationpublisher provides the Redis-Streams-backed
|
||||
// notification-intent publisher Game Master uses for the three GM-owned
|
||||
// types listed in `gamemaster/README.md §Notification Contracts`:
|
||||
// `game.turn.ready`, `game.finished`, `game.generation_failed`.
|
||||
//
|
||||
// The adapter is a thin shim over `galaxy/notificationintent.Publisher`
|
||||
// that drops the entry id at the wrapper boundary; it mirrors
|
||||
// `rtmanager/internal/adapters/notificationpublisher` byte-for-byte
|
||||
// (`rtmanager/docs/domain-and-ports.md §7` justifies that decision and
|
||||
// applies here for the same reason).
|
||||
package notificationpublisher
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"github.com/redis/go-redis/v9"
|
||||
|
||||
"galaxy/notificationintent"
|
||||
|
||||
"galaxy/gamemaster/internal/ports"
|
||||
)
|
||||
|
||||
// Config groups the dependencies and stream name required to construct
|
||||
// a Publisher.
|
||||
type Config struct {
|
||||
// Client appends entries to Redis Streams. Must be non-nil.
|
||||
Client *redis.Client
|
||||
|
||||
// Stream stores the Redis Stream key intents are published to.
|
||||
// When empty, `notificationintent.DefaultIntentsStream` is used.
|
||||
Stream string
|
||||
}
|
||||
|
||||
// Publisher implements `ports.NotificationIntentPublisher` on top of
|
||||
// the shared `notificationintent.Publisher`.
|
||||
type Publisher struct {
|
||||
inner *notificationintent.Publisher
|
||||
}
|
||||
|
||||
// NewPublisher constructs a Publisher from cfg. Validation errors and
|
||||
// transport errors propagate verbatim.
|
||||
func NewPublisher(cfg Config) (*Publisher, error) {
|
||||
if cfg.Client == nil {
|
||||
return nil, errors.New("new gamemaster notification publisher: nil redis client")
|
||||
}
|
||||
inner, err := notificationintent.NewPublisher(notificationintent.PublisherConfig{
|
||||
Client: cfg.Client,
|
||||
Stream: cfg.Stream,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("new gamemaster notification publisher: %w", err)
|
||||
}
|
||||
return &Publisher{inner: inner}, nil
|
||||
}
|
||||
|
||||
// Publish forwards intent to the underlying notificationintent
|
||||
// publisher and discards the resulting Redis Stream entry id. A failed
|
||||
// publish surfaces as the underlying error.
|
||||
func (publisher *Publisher) Publish(ctx context.Context, intent notificationintent.Intent) error {
|
||||
if publisher == nil || publisher.inner == nil {
|
||||
return errors.New("publish notification intent: nil publisher")
|
||||
}
|
||||
if _, err := publisher.inner.Publish(ctx, intent); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Compile-time assertion: Publisher implements
|
||||
// ports.NotificationIntentPublisher.
|
||||
var _ ports.NotificationIntentPublisher = (*Publisher)(nil)
|
||||
Reference in New Issue
Block a user