Documentation
¶
Overview ¶
Package app is the composition root. NewApplication connects the database, Redis, the GeoIP database and the task queue, and assembles the shared store, the seven module facades and the event bus on them; NewServices returns the services the process runs: the HTTP server with its runtime bootstrap, the task worker and the scheduler. Only cmd imports this package, which internal/arch enforces.
Index ¶
- func NewAsynqClient(c config.Config) *taskqueue.Client
- func NewAsynqInspector(c config.Config) *asynq.Inspector
- func NewDeviceManager(srv *Application) *devicesocket.DeviceManager
- func NewServices(c config.Config) *lifecycle.Group
- func NewStore(db *gorm.DB, rds *redis.Client) *repository.GormStore
- func QueueRedisOpt(c config.Config) asynq.RedisClientOpt
- type Application
- type Dependencies
- type DeviceMessage
- type DeviceMessageMethod
- type IdentityStartup
- type Service
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func NewAsynqClient ¶
NewAsynqClient returns the tracing asynq client: EnqueueContext stamps the caller's trace context onto the task for the worker-side middleware to resume. Pass task options to EnqueueContext, not NewTask — wrapping rebuilds the task.
func NewAsynqInspector ¶
NewAsynqInspector returns the queue inspector with which the paid-order reconciler repairs conflicting activation tasks.
func NewDeviceManager ¶
func NewDeviceManager(srv *Application) *devicesocket.DeviceManager
NewDeviceManager builds the device WebSocket manager. The devices' presence is the identity module's: the online and offline callbacks record it through the identity facade, resolved when a callback runs because the manager is built before the facade. The socket has no one to report a failed record to, so it is only logged. Browsers may connect from the boot configuration's AllowedOrigins; none configured admits every origin, as the CORS middleware does.
func NewServices ¶ added in v1.21.0
NewServices assembles the application from the configuration and returns the services the process runs: the HTTP server with the runtime bootstrap, the task worker and the scheduler.
func NewStore ¶
NewStore assembles the shared store from the module-owned repository builders over one connection pool: each module owns its persistence, and a module moved to its own database only points its builder at another connection (ADR-001).
func QueueRedisOpt ¶ added in v1.21.0
func QueueRedisOpt(c config.Config) asynq.RedisClientOpt
QueueRedisOpt is the task queue's Redis connection, shared by the task client, the consumer and the periodic scheduler. The queue lives in the Redis database Redis.QueueDB names (5 unless the file says otherwise), so two deployments sharing one Redis keep their queues apart by giving each its own value; the producer, the consumer and the scheduler read it from here only.
Types ¶
type Application ¶
type Application struct {
// DB is the application's connection pool; the readiness endpoint
// pings it. The modules reach the database through Store.
DB *gorm.DB
Redis *redis.Client
Runtime *state.State
Queue *taskqueue.Client
Inspector *asynq.Inspector
ExchangeRate *billing.CurrencyRateCache
// GeoIP is the open GeoIP database, nil when none is available: the
// request metadata then carries no location, and Enrich is a no-op.
GeoIP *geoip.IPLocation
Store repository.Store
// Domain modules (see docs/design/adr-001-modular-monolith.md). Application is
// their composition root; handlers call the module facades.
Support support.Service
Billing billing.Service
Platform platform.Service
Subscription subscription.Service
Identity identity.Service
Network network.Service
Notification notification.Service
EventBus *eventbus.Bus
// TrafficUsage books reported traffic against the subscriptions; the
// node API and the traffic flush share the one instance.
TrafficUsage subscription.TrafficUsage
AuthLimiter *ratelimit.PeriodLimit
DeviceManager *devicesocket.DeviceManager
}
Application is the assembled process: the infrastructure connections, the runtime state and the seven module facades, from which the services the process runs are built.
func NewApplication ¶
func NewApplication(c config.Config) *Application
NewApplication connects the database, Redis and the task queue the configuration names, opens the GeoIP database when one is available, and assembles the application on them. It panics when a connection fails: nothing can run without them. The GeoIP database is optional unless the configuration requires it.
func (*Application) DeviceSocketHandler ¶ added in v1.21.0
func (srv *Application) DeviceSocketHandler() app.HandlerFunc
DeviceSocketHandler returns the Hertz handler of the device WebSocket route, GET /v1/app/ws/:userid/:identifier, which the routes register behind the session authentication. A user may keep as many sockets open as the largest device limit among their unexpired subscriptions allows, as the route computed it before it went unregistered; without one the manager's default cap applies.
type Dependencies ¶
type Dependencies struct {
Config func() config.Config
Bootstrap *bootstrap.Dependencies
HTTP func() httpserver.Dependencies
SetRestart func(func() error)
SetReinitializeHandler func(func(string) error)
// Identity runs the identity module's startup check and data fix-up
// once the bootstrap migrated the schema; the identity facade provides
// it.
Identity IdentityStartup
// Bootstrapped tells the services that read the runtime settings, the
// task worker among them, that the bootstrap published them or failed.
// The readiness endpoint reports it too.
Bootstrapped *lifecycle.Readiness
// Probes are the dependencies the readiness endpoint pings: the
// database and Redis.
Probes []httpserver.Probe
}
Dependencies is what the HTTP service needs to start and restart: the runtime configuration and the bootstrap that loads it, the identity module's startup work, the routes and the runtime hooks it installs.
type DeviceMessage ¶
type DeviceMessage struct {
Method DeviceMessageMethod `json:"method"`
}
DeviceMessage is a message the server pushes to a connected device.
func (*DeviceMessage) Json ¶
func (dm *DeviceMessage) Json() string
Json encodes the message as the device protocol's JSON text.
type DeviceMessageMethod ¶
type DeviceMessageMethod string
DeviceMessageMethod names what a device message tells the device.
const ( // DeviceKickedMax tells a device it was signed out because its user // signed in on more devices than the limit allows. DeviceKickedMax DeviceMessageMethod = "kicked_device" // DeviceKickedAdmin tells a device an administrator signed it out. DeviceKickedAdmin DeviceMessageMethod = "kicked_admin" // SubscribeUpdate tells a device its subscription changed. SubscribeUpdate DeviceMessageMethod = "subscribe_update" )
type IdentityStartup ¶ added in v1.21.0
type IdentityStartup interface {
ValidateEmailIdentities(ctx context.Context) error
NormalizePhoneNumbers(ctx context.Context) error
}
IdentityStartup is the identity module's part of the server start: the check that refuses stored email bindings email sign-in cannot tell apart, and the fix-up that stores phone numbers in E.164.
type Service ¶
type Service struct {
// contains filtered or unexported fields
}
Service is the HTTP service: it runs the bootstrap, then serves the routes, and restarts the server when an administrator changes the subscribe path.
func NewService ¶
func NewService(deps Dependencies) *Service
NewService builds the HTTP service; Start runs the bootstrap.
func (*Service) Restart ¶
Restart applies the runtime settings the routes are built from — the subscribe path — and serves them from a new server: it reloads the settings, builds the new server, shuts the old one down and starts the new one. An administrator's request triggers it, and that request is served by the server being shut down, so the shutdown runs on its own context. It does not re-run the bootstrap (migration and seeding are startup work), and it reports a failure instead of ending the process: a failed reload keeps the previous settings and the running server, a certificate that does not load keeps the running server, and a new server that cannot listen is reported to the caller and logged.
func (*Service) Start ¶
func (m *Service) Start()
Start loads the runtime configuration, installs the runtime hooks and serves until Stop or Restart. It ends the process when the bootstrap fails or the server cannot listen: a process without an API that still consumed tasks would look healthy to the orchestrator.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package bootstrap loads the runtime configuration at startup and reloads a subsystem's part of it when an administrator changes its settings: it runs the database migration, seeds the first administrator, provisions the node secret and publishes each subsystem's stored settings (site, node, email, device, invite, verification, subscription, registration, mobile, currency and Telegram) into the process's runtime snapshot.
|
Package bootstrap loads the runtime configuration at startup and reloads a subsystem's part of it when an administrator changes its settings: it runs the database migration, seeds the first administrator, provisions the node secret and publishes each subsystem's stored settings (site, node, email, device, invite, verification, subscription, registration, mobile, currency and Telegram) into the process's runtime snapshot. |
|
Package buildinfo holds the version, build time and release channel the build scripts inject, for the CLI and the admin version endpoint.
|
Package buildinfo holds the version, build time and release channel the build scripts inject, for the CLI and the admin version endpoint. |
|
Package lifecycle runs the process's services as one group: started together and stopped once, in the reverse order they were added, with the log output closed last so the lines written while stopping reach the log files.
|
Package lifecycle runs the process's services as one group: started together and stopped once, in the reverse order they were added, with the log output closed last so the lines written while stopping reach the log files. |
|
migration
|
|
|
mysql2postgres
Package mysql2postgres copies the data of a MySQL or MariaDB installation into a PostgreSQL database whose schema the migrations created: the rows of the tables and columns both databases have, in foreign-key order, for the migrate mysql2postgres command.
|
Package mysql2postgres copies the data of a MySQL or MariaDB installation into a PostgreSQL database whose schema the migrations created: the rows of the tables and columns both databases have, in foreign-key order, for the migrate mysql2postgres command. |
|
schema
Package schema migrates the database schema with the SQL migrations of both dialects embedded in the binary, and seeds the first administrator of a fresh installation.
|
Package schema migrates the database schema with the SQL migrations of both dialects embedded in the binary, and seeds the first administrator of a fresh installation. |
|
Package scheduler enqueues the periodic tasks on their schedules, in the application's time zone.
|
Package scheduler enqueues the periodic tasks on their schedules, in the application's time zone. |
|
Package state owns the process-wide mutable runtime state.
|
Package state owns the process-wide mutable runtime state. |