Skip to content

Queues & Octane

Notify classes generated by notify:make implement ShouldQueue. Nothing is cached: every value is read from the database when it is needed. For a queued notification that splits in two moments:

  • At dispatch Laravel calls via() to queue one job per channel. Opt-outs, user channels and the subscription are evaluated then. In the worker via() is not called again.
  • In the worker each job calls to{Channel}(), so templates and buttons are the ones in the database when the job runs.

Other points:

  • Notification uses SerializesModels: constructor models are re-fetched in the worker.
  • The tenant set in the constructor ($this->tenantId) travels with the job; a tenant from a tenant_id callable is resolved again in the worker for templates — see Multi-tenancy.
  • delay() takes seconds; NotifyTemplates::resolveDelay() converts the subscription’s options.delay minutes into seconds.

The NotifyTemplatesManager singleton holds only the type registry, filled once when the application boots. Nothing request-specific is stored in it; every resolve method queries the database on each call.

Call registerType(), registerTypes() and discoverIn() only from a service provider’s boot(). A call during a request changes the registry for every following request of that worker.

Optionally resolve the singleton when the worker starts:

config/octane.php
'warm' => [
...Octane::defaultServicesToWarm(),
\Fomvasss\NotifyTemplates\NotifyTemplatesManager::class,
],

Each via() runs up to three queries: two on notify_user_settings (the opt-out and the channel override read the same row separately; both skipped for non-configurable types and non-model notifiables) and one on the subscription. Each toMail() / getMessengerBody() adds a template query or two, and button helpers one each. Nothing is cached; for bulk sends to thousands of users this is per recipient.