Documentation
¶
Overview ¶
Package gorch orchestrates the lifecycle of long-running goroutines.
It is a small, dependency-light runtime supervisor for a Go program that starts several cooperating services and must start, stop, and supervise them in a defined order.
What it does ¶
- Starts services in dependency order and stops them in reverse order.
- Runs cron-scheduled ticks and one-shot init (runOnce) gates.
- Self-heals services that crash, using a factory plus backoff and retry.
- Probes health and readiness and can restart unhealthy services.
- Carries a topic pub-sub Messenger between services.
Use case ¶
gorch is for the composition root of a single process: the place where you wire a handful of long-lived components (an HTTP server, a worker pool, a cache refresher, migrations) and want deterministic startup, supervision, and graceful shutdown without adopting a framework.
What it is not ¶
gorch is not a scheduler for distributed work, a durable queue, a service mesh, or a replacement for context. It supervises goroutines inside one process and nothing more. It does not persist state across restarts, retry with deduplication, or guarantee delivery of messages.
Contract ¶
- Lifecycle is single-shot: after a successful Stop the orchestrator cannot be restarted.
- The wire format is encoding/gob and is part of the public contract; types passed through the typed Messenger helpers must be gob-compatible.
- Publish is drop-only: when a subscriber's buffer is full the message is dropped for that subscriber.
See the README for the concurrency table and the per-method guarantees.
Index ¶
- Variables
- func RegisterType[T any](m *Messenger) error
- func TypedPublish[T any](m *Messenger, msg T, topics ...string)
- func TypedRequest[TReq, TResp any](m *Messenger, ctx context.Context, req TReq, topic string) (TResp, error)
- func TypedRespond[TResp any](m *Messenger, resp TResp, replyTopic string)
- func TypedSubscribe[T any](m *Messenger, topic string) (<-chan T, func())
- func TypedSubscribeRequest[TReq any](m *Messenger, topic string) (<-chan TypedEnvelope[TReq], func())
- type Backoff
- type ConstantBackoff
- type CronMode
- type ExponentialBackoff
- type HealthCheckOption
- type HealthChecker
- type LogLevel
- type Logger
- type Message
- type Messenger
- func (m *Messenger) Drain()
- func (m *Messenger) Publish(msg any, topics ...string)
- func (m *Messenger) Request(ctx context.Context, msg any, topic string) (any, error)
- func (m *Messenger) RequestAsync(ctx context.Context, msg any, topic string) (<-chan any, error)
- func (m *Messenger) Subscribe(topic string) (<-chan any, func())
- func (m *Messenger) SubscribeWithBuffer(topic string, bufSize int) (<-chan any, func())
- type Metrics
- type Option
- func WithAfterHealthCheck(fn func(name string, err error)) Option
- func WithBeforeHealthCheck(fn func(name string) error) Option
- func WithDefaultStartTimeout(d time.Duration) Option
- func WithGlobalOnAfterStart(fn func(name string, err error)) Option
- func WithGlobalOnAfterStop(fn func(name string, err error)) Option
- func WithGlobalOnBeforeStart(fn func(name string) error) Option
- func WithGlobalOnBeforeStop(fn func(name string) error) Option
- func WithHealthChecks(interval time.Duration, opts ...HealthCheckOption) Option
- func WithHealthChecksDisabled() Option
- func WithLogLevel(lvl LogLevel) Option
- func WithLogger(l Logger) Option
- func WithOnCrash(fn func(name string, err error)) Option
- func WithOnStateChange(fn func(name string, from, to ServiceStatus)) Option
- type Orchestrator
- func (o *Orchestrator) Count() int
- func (o *Orchestrator) Done() <-chan struct{}
- func (o *Orchestrator) Health() map[string]error
- func (o *Orchestrator) IsReady(ctx context.Context, name string) bool
- func (o *Orchestrator) Metrics() Metrics
- func (o *Orchestrator) Names() []string
- func (o *Orchestrator) Register(svc Service, opts ...RegisterOption) error
- func (o *Orchestrator) RegisterFunc(name string, startFn func(ctx ServiceContext) error, stopFn func() error, ...) error
- func (o *Orchestrator) Run(stopTimeout time.Duration, signals ...os.Signal) error
- func (o *Orchestrator) Start() error
- func (o *Orchestrator) StartGroup(group string) error
- func (o *Orchestrator) Status(name string) (ServiceStatus, bool)
- func (o *Orchestrator) Statuses() map[string]ServiceStatus
- func (o *Orchestrator) StatusesByGroup(group string) map[string]ServiceStatus
- func (o *Orchestrator) StatusesByLabel(key, value string) map[string]ServiceStatus
- func (o *Orchestrator) Stop(timeout time.Duration) error
- func (o *Orchestrator) StopGroup(group string, timeout time.Duration) error
- func (o *Orchestrator) WaitFor(name string, target ServiceStatus, timeout time.Duration) error
- type ReadinessChecker
- type RegisterOption
- func DependsOn(names ...string) RegisterOption
- func DependsOnSoft(names ...string) RegisterOption
- func WithBackoff(b Backoff) RegisterOption
- func WithCron(spec string, mode CronMode) RegisterOption
- func WithGroup(name string) RegisterOption
- func WithLabel(key, value string) RegisterOption
- func WithMaxRetries(max int) RegisterOption
- func WithName(name string) RegisterOption
- func WithOnAfterStart(fn func(name string, err error)) RegisterOption
- func WithOnAfterStop(fn func(name string, err error)) RegisterOption
- func WithOnBeforeStart(fn func(name string) error) RegisterOption
- func WithOnBeforeStop(fn func(name string) error) RegisterOption
- func WithResetAfter(d time.Duration) RegisterOption
- func WithRunOnce() RegisterOption
- func WithSelfHeal(factory func() Service) RegisterOption
- func WithStartCondition(fn func() bool) RegisterOption
- func WithStartTimeout(d time.Duration) RegisterOption
- func WithStopTimeout(d time.Duration) RegisterOption
- type Service
- type ServiceContext
- type ServiceLogger
- type ServiceStatus
- type TypedEnvelope
- type Validator
Constants ¶
This section is empty.
Variables ¶
var ( ErrAlreadyStarted = errors.New("gorch: orchestrator already started") ErrInvalidCron = errors.New("gorch: invalid cron expression") ErrStopTimeout = errors.New("gorch: stop timed out waiting for services") ErrDuplicateName = errors.New("gorch: duplicate service name") ErrDependencyCycle = errors.New("gorch: dependency cycle detected") ErrStartAborted = errors.New("gorch: start aborted due to dependency failure") ErrUnsupportedOption = errors.New("gorch: unsupported option combination") )
Sentinel errors
Functions ¶
func RegisterType ¶
RegisterType registers T with encoding/gob so it can be used with TypedPublish and TypedSubscribe. Must be called before any typed operations for the type. Recovers from gob panics and returns an error if the type is not gob-compatible. Thread-safe. ponytail: standalone func (not method) because Go does not support generic methods on non-generic types.
func TypedPublish ¶
TypedPublish gob-encodes msg and publishes it as a Message to the given topics. Silently drops the message if the type has not been registered via RegisterType. Thread-safe.
func TypedRequest ¶
func TypedRequest[TReq, TResp any](m *Messenger, ctx context.Context, req TReq, topic string) (TResp, error)
TypedRequest sends a typed request and waits for a typed response. It gob-encodes the request, publishes it via requestMessage, and gob-decodes the response. Returns the decoded response or an error.
func TypedRespond ¶
TypedRespond gob-encodes resp and publishes it to replyTopic. Pair with TypedSubscribeRequest to implement a typed request responder. Silently drops the reply if the type is not gob-encodable. Thread-safe.
func TypedSubscribe ¶
TypedSubscribe subscribes to topic and returns a typed receive-only channel and an unsubscribe function. Messages published via TypedPublish are gob-decoded into T before delivery. Non-Message values and unrecognized types are silently dropped. Thread-safe.
func TypedSubscribeRequest ¶
func TypedSubscribeRequest[TReq any](m *Messenger, topic string) (<-chan TypedEnvelope[TReq], func())
TypedSubscribeRequest subscribes to topic and returns a channel of decoded request envelopes. Pair with TypedRespond to reply. Non-Message values and decode failures are silently dropped. Thread-safe.
Types ¶
type Backoff ¶
Backoff computes the delay before the next retry attempt. retry is 1-based (first retry = 1).
type ConstantBackoff ¶
ConstantBackoff always returns the same delay regardless of retry count.
type CronMode ¶
type CronMode int
const ( CronParallel CronMode = iota // fire in new goroutine regardless // CronQueue serializes ticks on a per-entry mutex: an overlapping tick // blocks until the previous one finishes. robfig/cron spawns a goroutine per // tick, so a long-running tick makes later ones pile up as blocked goroutines. CronQueue CronSkip // drop this tick entirely )
type ExponentialBackoff ¶
ExponentialBackoff produces delays: initial * factor^(retry-1), capped at max. ponytail: no jitter; add WithJitter(bool) if thundering-herd becomes a problem.
type HealthCheckOption ¶
type HealthCheckOption func(*config)
HealthCheckOption refines the periodic health-check loop configured by WithHealthChecks. It exists so the probe timeout and failure threshold cannot be swapped by position at the call site.
func WithFailureThreshold ¶
func WithFailureThreshold(n int) HealthCheckOption
WithFailureThreshold sets how many consecutive probe failures are tolerated before a self-healing service is restarted. Zero falls back to the default (3).
func WithProbeTimeout ¶
func WithProbeTimeout(d time.Duration) HealthCheckOption
WithProbeTimeout sets the per-probe deadline for each health check. Zero falls back to the default (5s).
type HealthChecker ¶
HealthChecker is implemented by services that can report their own health. Health is called periodically by the orchestrator. A non-nil error means the service is unhealthy.
type Message ¶
Message is the envelope for typed pub-sub and request-reply messaging. Publishers encode their payload into Payload; subscribers decode it. ReplyTopic is set automatically by Request/RequestAsync so responders know where to send the reply.
type Messenger ¶
type Messenger struct {
// contains filtered or unexported fields
}
func (*Messenger) Drain ¶
func (m *Messenger) Drain()
Drain closes all subscriber channels and clears all subscriptions. Buffered messages are delivered to receivers before they observe the close. After Drain, the Messenger is empty, Publish is a no-op, and a subsequent Subscribe re-initializes the subscription map. Thread-safe.
func (*Messenger) Publish ¶
Publish sends msg to subscribers. Non-blocking: if a subscriber's channel is full, the message is dropped for that subscriber. Thread-safe. If topics is empty or nil, broadcasts to ALL subscribers on every topic.
func (*Messenger) Request ¶
Request publishes a request message and waits for a single reply. It creates a temporary reply topic, subscribes to it, publishes the request, and returns the first response (or an error if ctx expires). The responding service receives a Message on its channel; it should Publish the response on msg.ReplyTopic. Thread-safe.
func (*Messenger) RequestAsync ¶
RequestAsync is like Request but returns immediately with a response channel. The caller must select on the channel and ctx.Done(). The returned channel is delivered to exactly once on reply, and the forwarding goroutine exits on either a reply or context cancellation. Thread-safe.
func (*Messenger) Subscribe ¶
Subscribe registers interest in a topic. Returns a receive-only channel and an unsubscribe function. The channel is buffered (cap 16). Thread-safe.
func (*Messenger) SubscribeWithBuffer ¶
SubscribeWithBuffer registers interest in a topic with a caller-specified buffer size. Returns a receive-only channel and an unsubscribe function. Safe to call after Drain (subscriptions are lazily re-initialized). Thread-safe.
type Option ¶
type Option func(*config)
Option configures an Orchestrator at construction via New.
func WithAfterHealthCheck ¶
WithAfterHealthCheck sets a hook fired after each health probe.
func WithBeforeHealthCheck ¶
WithBeforeHealthCheck sets a hook fired before each health probe.
func WithDefaultStartTimeout ¶
WithDefaultStartTimeout sets the default per-service start deadline. 0 means no timeout (use WithStartTimeout per-service).
func WithGlobalOnAfterStart ¶
WithGlobalOnAfterStart sets a global hook called after each service's Start returns.
func WithGlobalOnAfterStop ¶
WithGlobalOnAfterStop sets a global hook called after each service's Stop returns.
func WithGlobalOnBeforeStart ¶
WithGlobalOnBeforeStart sets a global hook called just before each service's Start.
func WithGlobalOnBeforeStop ¶
WithGlobalOnBeforeStop sets a global hook called just before each service's Stop.
func WithHealthChecks ¶
func WithHealthChecks(interval time.Duration, opts ...HealthCheckOption) Option
WithHealthChecks enables periodic health checks at the given interval. The probe timeout and failure threshold default to 5s and 3; override them with WithProbeTimeout and WithFailureThreshold. An interval of zero enables the loop at the default 30s. Use WithHealthChecksDisabled to turn it off.
func WithHealthChecksDisabled ¶
func WithHealthChecksDisabled() Option
WithHealthChecksDisabled disables the periodic health-check loop entirely.
func WithLogLevel ¶
WithLogLevel sets the minimum log level. Defaults to LogLevelInfo when absent. Ignored when a custom Logger is set.
func WithLogger ¶
WithLogger sets a custom logger. When set, gorch sends all log output through it instead of the built-in stderr logger.
func WithOnCrash ¶
WithOnCrash sets a callback fired when a service reaches StatusCrashed.
func WithOnStateChange ¶
func WithOnStateChange(fn func(name string, from, to ServiceStatus)) Option
WithOnStateChange sets a callback fired on every status transition.
type Orchestrator ¶
type Orchestrator struct {
// contains filtered or unexported fields
}
Orchestrator manages service lifecycles.
func New ¶
func New(opts ...Option) *Orchestrator
New creates a new Orchestrator. Each call returns a fresh, independent instance. Orchestrators can be nested: a service may create its own gorch to manage sub-services. Configure via Option functions; the zero-option call uses the defaults (LogLevelInfo, health checks every 30s with a 5s probe timeout).
func (*Orchestrator) Count ¶
func (o *Orchestrator) Count() int
Count returns the total number of registered services. Thread-safe.
func (*Orchestrator) Done ¶
func (o *Orchestrator) Done() <-chan struct{}
Done returns a channel that closes when all managed goroutines (services, log-pump, health-check loop) have exited. The orchestrator must be stopped (via Stop or Run returning) before the channel closes. The channel is created lazily and cached: repeated calls return the same channel.
func (*Orchestrator) Health ¶
func (o *Orchestrator) Health() map[string]error
func (*Orchestrator) IsReady ¶
func (o *Orchestrator) IsReady(ctx context.Context, name string) bool
Health probes all registered services that implement HealthChecker. Returns a map of service name to error (nil = healthy). Services that don't implement HealthChecker are reported as nil. Thread-safe. IsReady reports whether a named service is running and ready to serve. The ReadinessChecker probe (if any) runs with the given ctx, so callers can bound how long they wait (e.g. IsReady(ctx, name) with a deadline context). Thread-safe.
func (*Orchestrator) Metrics ¶
func (o *Orchestrator) Metrics() Metrics
Metrics returns a snapshot of orchestrator-level event counters.
func (*Orchestrator) Names ¶
func (o *Orchestrator) Names() []string
Names returns the names of all registered services in registration order. Thread-safe.
func (*Orchestrator) Register ¶
func (o *Orchestrator) Register(svc Service, opts ...RegisterOption) error
Register adds a service to the orchestrator. Must be called before Start(). Returns ErrAlreadyStarted if the orchestrator has already been started. Returns ErrDuplicateName if WithName conflicts with another service. Returns ErrDependencyCycle if DependsOn introduces a cycle. Thread-safe.
func (*Orchestrator) RegisterFunc ¶
func (o *Orchestrator) RegisterFunc(name string, startFn func(ctx ServiceContext) error, stopFn func() error, opts ...RegisterOption) error
RegisterFunc registers a closure-based service under the given name. Thread-safe.
func (*Orchestrator) Run ¶
Run starts the orchestrator, blocks on SIGINT/SIGTERM, then stops. Returns any error from Start or aggregated errors from Stop. Optional signals override the default signal set (SIGINT, SIGTERM).
func (*Orchestrator) Start ¶
func (o *Orchestrator) Start() error
Start begins the orchestrator lifecycle. Returns ErrAlreadyStarted if already started. If Start fails, the orchestrator is reset and may be started again (e.g. to retry after a transient dependency failure). A persistent service that returns an error synchronously aborts Start only when a start timeout is set; without one its launch is fire-and-forget by construction. An orchestrator is single-shot: after a successful Stop it cannot be restarted; a subsequent Start (or Register) returns ErrAlreadyStarted. Thread-safe.
func (*Orchestrator) StartGroup ¶
func (o *Orchestrator) StartGroup(group string) error
StartGroup starts all services in the named group in topological order.
func (*Orchestrator) Status ¶
func (o *Orchestrator) Status(name string) (ServiceStatus, bool)
Status returns the current lifecycle status of a named service. ok is false if no service with that name is registered. Thread-safe.
func (*Orchestrator) Statuses ¶
func (o *Orchestrator) Statuses() map[string]ServiceStatus
Statuses returns a map of service name to status for all registered services. Thread-safe.
func (*Orchestrator) StatusesByGroup ¶
func (o *Orchestrator) StatusesByGroup(group string) map[string]ServiceStatus
StatusesByGroup returns a map of service name to status for all services in the named group. Thread-safe.
func (*Orchestrator) StatusesByLabel ¶
func (o *Orchestrator) StatusesByLabel(key, value string) map[string]ServiceStatus
StatusesByLabel returns a map of service name to status for all services matching the given label key-value pair. Thread-safe.
func (*Orchestrator) Stop ¶
func (o *Orchestrator) Stop(timeout time.Duration) error
Stop shuts down the orchestrator, waiting up to timeout for services to finish. Returns aggregated errors from all Stop failures, or ErrStopTimeout if services don't all stop within the timeout. Thread-safe. Safe to call on an orchestrator that was never started (no-op). An orchestrator is single-shot: after a successful Stop it cannot be restarted; a subsequent Start (or Register) returns ErrAlreadyStarted.
func (*Orchestrator) StopGroup ¶
func (o *Orchestrator) StopGroup(group string, timeout time.Duration) error
StopGroup stops all non-cron, non-runOnce services in the named group in reverse topological order. Errors are aggregated via errors.Join.
func (*Orchestrator) WaitFor ¶
func (o *Orchestrator) WaitFor(name string, target ServiceStatus, timeout time.Duration) error
WaitFor blocks until the named service reaches target status or timeout expires. Polls at 50ms intervals. Returns an error on timeout or if the service is not found.
type ReadinessChecker ¶
ReadinessChecker is implemented by services that distinguish "running" from "ready to serve". Ready returns nil when the service can accept traffic.
type RegisterOption ¶
type RegisterOption func(*registerConfig)
RegisterOption — functional options for Register.
func DependsOn ¶
func DependsOn(names ...string) RegisterOption
DependsOn declares that this service must start after the named services and stop before them. Cycles are detected at registration time.
func DependsOnSoft ¶
func DependsOnSoft(names ...string) RegisterOption
DependsOnSoft declares soft dependencies: start after the named services if they are present, but ignore any that are not registered.
func WithBackoff ¶
func WithBackoff(b Backoff) RegisterOption
WithBackoff sets the backoff strategy for self-heal restarts. If nil or not set, the default is 1s constant backoff.
func WithCron ¶
func WithCron(spec string, mode CronMode) RegisterOption
WithCron registers the service to run on a 6-field cron schedule (seconds included).
func WithGroup ¶
func WithGroup(name string) RegisterOption
WithGroup assigns the service to a named group for filtering.
func WithLabel ¶
func WithLabel(key, value string) RegisterOption
WithLabel attaches a key-value label to the service for filtering.
func WithMaxRetries ¶
func WithMaxRetries(max int) RegisterOption
WithMaxRetries sets the maximum number of self-heal restarts. 0 means unlimited (up to context cancellation). After the limit is reached, the service transitions to StatusStopped.
func WithName ¶
func WithName(name string) RegisterOption
WithName assigns a human-readable name used for dependency ordering, status queries, and lifecycle hooks. Names must be unique across all registered services.
func WithOnAfterStart ¶
func WithOnAfterStart(fn func(name string, err error)) RegisterOption
WithOnAfterStart sets a per-service hook called after Start() returns.
func WithOnAfterStop ¶
func WithOnAfterStop(fn func(name string, err error)) RegisterOption
WithOnAfterStop sets a per-service hook called after Stop() returns.
func WithOnBeforeStart ¶
func WithOnBeforeStart(fn func(name string) error) RegisterOption
WithOnBeforeStart sets a per-service hook called just before Start(). If the hook returns an error, Start() is aborted for this service.
func WithOnBeforeStop ¶
func WithOnBeforeStop(fn func(name string) error) RegisterOption
WithOnBeforeStop sets a per-service hook called just before Stop(). If the hook returns an error, Stop() is still called.
func WithResetAfter ¶
func WithResetAfter(d time.Duration) RegisterOption
WithResetAfter sets a stability window. If the service runs continuously for this duration without crashing, the retry counter resets to zero.
func WithRunOnce ¶
func WithRunOnce() RegisterOption
WithRunOnce marks a service as a one-shot init task. It runs before persistent services and transitions to StatusSucceeded when Start returns. Stop() is called at orchestrator shutdown — make Stop idempotent. If Start returns an error, startup aborts.
func WithSelfHeal ¶
func WithSelfHeal(factory func() Service) RegisterOption
WithSelfHeal enables auto-restart: when the service crashes (returns error or panics), the orchestrator calls factory() for a fresh instance and restarts it.
func WithStartCondition ¶
func WithStartCondition(fn func() bool) RegisterOption
WithStartCondition sets a function called at startup. If it returns false, the service is skipped (not started). nil or not set means always start.
func WithStartTimeout ¶
func WithStartTimeout(d time.Duration) RegisterOption
WithStartTimeout sets the maximum time to wait for this service's Start to return. Overrides Config.DefaultStartTimeout. A zero duration means no timeout (use with caution). With a timeout, a synchronous error from a persistent service's Start aborts the whole orchestrator Start (deterministic failure); without one the launch is fire-and-forget. Self-heal services are never aborted this way: an exit is handled by their restart policy.
func WithStopTimeout ¶
func WithStopTimeout(d time.Duration) RegisterOption
WithStopTimeout sets a per-service timeout on Stop(). If Stop() does not return within this duration, the orchestrator proceeds with shutdown.
type Service ¶
type Service interface {
Start(ctx ServiceContext) error // blocks; for cron: runs per-tick; for non-cron: runs until ctx cancelled
Stop() error // cleanup signal beyond context cancellation
}
type ServiceContext ¶
type ServiceContext struct {
context.Context
Logger *ServiceLogger
Messenger *Messenger
}
ServiceContext — what the orchestrator hands each service. Embeds context.Context so it satisfies the context.Context interface and can be passed directly to Service.Start. Carries the orchestrator's cancellation context.
type ServiceLogger ¶
type ServiceLogger struct {
// contains filtered or unexported fields
}
ServiceLogger — a logger that doesn't log; it sends entries to gorch's log channel. gorch consumes the channel and does the actual output (formatting, writing to stderr). When a custom Logger is set via Config.Logger, ServiceLogger delegates to it instead of the channel, prepending "service"=<name> to the key-value pairs.
func (*ServiceLogger) Debug ¶
func (l *ServiceLogger) Debug(msg string, args ...any)
func (*ServiceLogger) Error ¶
func (l *ServiceLogger) Error(msg string, args ...any)
func (*ServiceLogger) Info ¶
func (l *ServiceLogger) Info(msg string, args ...any)
func (*ServiceLogger) Warn ¶
func (l *ServiceLogger) Warn(msg string, args ...any)
type ServiceStatus ¶
type ServiceStatus int
ServiceStatus represents the lifecycle state of a registered service.
const ( StatusRegistered ServiceStatus = iota StatusStarting StatusRunning StatusStopping StatusStopped StatusCrashed // StatusSucceeded marks a runOnce service whose Start completed without // error: it is a successful gate, distinct from StatusStopped so dependents // are not aborted by a gate that did its job. StatusSucceeded )
func (ServiceStatus) String ¶
func (s ServiceStatus) String() string
String returns a human-readable name for the status.
type TypedEnvelope ¶
TypedEnvelope carries a decoded typed request value together with the reply topic the responder should publish to. Produced by TypedSubscribeRequest.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
examples
|
|
|
advanced
command
Advanced example: groups, labels, soft dependencies, RegisterFunc, Validator, ReadinessChecker, HealthChecker, state-change hooks, health-check hooks, WithStartCondition, WaitFor, Metrics, and Done().
|
Advanced example: groups, labels, soft dependencies, RegisterFunc, Validator, ReadinessChecker, HealthChecker, state-change hooks, health-check hooks, WithStartCondition, WaitFor, Metrics, and Done(). |
|
basic
command
Basic example: service lifecycle, cron scheduling, and graceful shutdown.
|
Basic example: service lifecycle, cron scheduling, and graceful shutdown. |
|
pubsub
command
Pub-sub example: services communicating via topics through the Messenger.
|
Pub-sub example: services communicating via topics through the Messenger. |
|
typedreq
command
Typed request-reply example: a service handles typed requests via TypedSubscribeRequest + TypedRespond, and a requester issues a TypedRequest.
|
Typed request-reply example: a service handles typed requests via TypedSubscribeRequest + TypedRespond, and a requester issues a TypedRequest. |