Documentation
¶
Overview ¶
Package email holds the queue handlers that send email: single notifications (verification codes, expiry, traffic and maintenance notices, custom mail) and the marketing campaigns administrators run in batches, together with the workers that pace a campaign and record its progress.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrTaskNotActive = errors.New("batch email task is no longer active")
ErrTaskNotActive stops a worker whose task an administrator cancelled or another run finished; the queue shell treats it as done, not failed.
Functions ¶
This section is empty.
Types ¶
type BatchEmailHandler ¶ added in v1.21.0
type BatchEmailHandler struct {
// contains filtered or unexported fields
}
BatchEmailHandler runs a marketing email campaign, the batch task an administrator created. The task row in the platform kernel's bookkeeping carries the campaign and its progress, so a campaign that reaches the daily sending limit continues from a follow-up task the next day, one that runs out of its run budget continues from a follow-up task at once, and a retried delivery resumes where the last run stopped.
func NewBatchEmailHandler ¶ added in v1.21.0
func NewBatchEmailHandler(deps Dependencies) *BatchEmailHandler
NewBatchEmailHandler builds the handler over the task bookkeeping, the message log, the queue and the runtime email settings.
func (*BatchEmailHandler) ProcessTask ¶ added in v1.21.0
type DailyLimitReached ¶
DailyLimitReached asks the queue shell to persist a continuation for the next civil day instead of keeping one queue worker asleep for hours.
func (*DailyLimitReached) Error ¶
func (e *DailyLimitReached) Error() string
type Dependencies ¶
type Dependencies struct {
Tasks repository.TaskRepo
Logs repository.LogRepo
Queue TaskScheduler
Email func() config.EmailConfig
SiteName func() string
// Recipients re-resolves a campaign's audience when a run starts, so
// accounts deleted since the campaign was created get no email; nil
// sends to the recorded recipients as they are.
Recipients RecipientResolver
}
Dependencies are the email tasks': the batch tasks' bookkeeping and the message log (the platform kernel's), the queue, the runtime settings and the identity facade's recipient selection.
type ErrorInfo ¶
type ErrorInfo struct {
Error string `json:"error"`
Email string `json:"email"`
Time int64 `json:"time"`
}
ErrorInfo is one failed delivery of a campaign, as the task records it.
type MessageLogStore ¶
type MessageLogStore interface {
Insert(ctx context.Context, data *logEntity.SystemLog) error
Update(ctx context.Context, data *logEntity.SystemLog) error
}
MessageLogStore is the message log a worker audits each delivery in.
type RecipientResolver ¶ added in v1.21.0
type RecipientResolver interface {
QueryEmailRecipients(ctx context.Context, filter *user.EmailRecipientFilter) ([]string, error)
}
RecipientResolver selects the accounts a campaign scope reaches today; the identity facade provides it.
type RunBudgetExhausted ¶ added in v1.21.0
RunBudgetExhausted asks the queue shell to continue the campaign from a follow-up task right away: the run's deadline (the queue's task timeout) is too close to pace another delivery, so the worker stopped after the last recipient it recorded instead of being cut off mid-run and retried with a backoff. Sent is the recipients delivered so far, the position the continuation resumes from; ResumeAt keeps the campaign's pacing across the two runs.
func (*RunBudgetExhausted) Error ¶ added in v1.21.0
func (e *RunBudgetExhausted) Error() string
type SendEmailHandler ¶ added in v1.21.0
type SendEmailHandler struct {
// contains filtered or unexported fields
}
SendEmailHandler sends one notification email. The body and subject come from the operator-configured templates of the notification type. The attempt is written to the message log before the provider call and finalized after it; once the provider was called the task is not retried, even on an error, because a failed call may still have delivered the mail.
func NewSendEmailHandler ¶ added in v1.21.0
func NewSendEmailHandler(deps Dependencies) *SendEmailHandler
NewSendEmailHandler builds the handler over the message log and the runtime email settings.
func (*SendEmailHandler) ProcessTask ¶ added in v1.21.0
type TaskScheduler ¶
type TaskScheduler interface {
EnqueueContext(ctx context.Context, task *asynq.Task, opts ...asynq.Option) (*asynq.TaskInfo, error)
}
TaskScheduler enqueues the follow-up task a campaign continues from once it reached the daily sending limit or the end of its run budget; the asynq client provides it.
type TaskStore ¶
type TaskStore interface {
FindOneByType(ctx context.Context, id int64, typ task.Type) (*task.Task, error)
UpdateActive(ctx context.Context, data *task.Task) (bool, error)
UpdateActiveProgress(ctx context.Context, data *task.Task) (bool, error)
UpdateActiveProgressWithError(ctx context.Context, data *task.Task, taskError *task.TaskError) (bool, error)
InsertError(ctx context.Context, data *task.TaskError) error
FindErrors(ctx context.Context, taskIDs []int64) ([]*task.TaskError, error)
}
TaskStore is the minimal task repository interface needed by the batch-email worker.
type Worker ¶
type Worker struct {
// contains filtered or unexported fields
}
Worker sends one campaign to its recipients, one at a time, recording the progress and every failure on the task so a later run resumes after the last recipient sent.
func NewWorker ¶
func NewWorker(ctx context.Context, id int64, tasks TaskStore, sender mail.Sender, options ...WorkerOption) *Worker
NewWorker builds the worker of task id; ctx bounds the run.
type WorkerManager ¶
type WorkerManager struct {
// contains filtered or unexported fields
}
WorkerManager owns asynchronous batch-email workers. It is an application worker, so it belongs in internal rather than the reusable email package.
var ( // Manager is the process's worker manager, created by the first // NewWorkerManager call. Manager *WorkerManager )
func NewWorkerManager ¶
func NewWorkerManager() *WorkerManager
NewWorkerManager returns the process's worker manager, creating it on the first call.
func (*WorkerManager) GetWorker ¶
func (m *WorkerManager) GetWorker(id int64) *Worker
GetWorker returns the worker currently assigned to id.
func (*WorkerManager) RemoveWorker ¶
func (m *WorkerManager) RemoveWorker(id int64)
RemoveWorker cancels and removes the worker assigned to id.
func (*WorkerManager) RunWorker ¶
func (m *WorkerManager) RunWorker(ctx context.Context, id int64, tasks TaskStore, sender mail.Sender, options ...WorkerOption) error
RunWorker keeps queue acknowledgement coupled to the actual campaign run. A duplicate delivery in the same process is harmless: the existing worker remains authoritative for that database task.
type WorkerOption ¶
type WorkerOption func(*Worker)
WorkerOption configures a Worker.
func WithMessageLogs ¶
func WithMessageLogs(logs MessageLogStore, platform string) WorkerOption
WithMessageLogs audits each delivery in logs under the provider platform.
func WithRecipientResolver ¶ added in v1.21.0
func WithRecipientResolver(recipients RecipientResolver) WorkerOption
WithRecipientResolver re-checks the campaign's recipients against the accounts its scope selects when the run starts, so an account deleted or no longer eligible since the campaign was created is skipped.