snapshot of https://github.com/ory/kratos.git (master, 2026-09-15; blobs > 131072B omitted)
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
Some checks failed
CI / Run tests and lints (push) Failing after 29s
CI / Build CLI docs (push) Has been skipped
CI / Run Playwright end-to-end tests (mysql) (push) Failing after 3s
CI / Run Playwright end-to-end tests (postgres) (push) Failing after 2s
CI / Run Playwright end-to-end tests (sqlite) (push) Failing after 3s
CodeQL / Analyze (go) (push) Failing after 4s
CodeQL / Analyze (javascript) (push) Failing after 3s
Docker Image Scanners / scanners (push) Failing after 4s
Synchronize Issue Labels / Synchronize Issue Labels (push) Has been skipped
CI / Run end-to-end tests (postgres) (push) Failing after 19s
CI / Run end-to-end tests (sqlite) (push) Failing after 2s
CI / Run Playwright end-to-end tests (cockroach) (push) Failing after 2s
CI / Draft newsletter (push) Has been skipped
CI / Generate release (push) Has been skipped
CI / Pending approval Slack notification (push) Has been skipped
CI / Send newsletter (push) Has been skipped
This commit is contained in:
108
courier/courier.go
Normal file
108
courier/courier.go
Normal file
@@ -0,0 +1,108 @@
|
||||
// Copyright © 2023 Ory Corp
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
package courier
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/cenkalti/backoff"
|
||||
"github.com/gofrs/uuid"
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"github.com/ory/x/httpx"
|
||||
"github.com/ory/x/jsonnetsecure"
|
||||
"github.com/ory/x/logrusx"
|
||||
"github.com/ory/x/otelx"
|
||||
|
||||
"github.com/ory/kratos/courier/template"
|
||||
"github.com/ory/kratos/driver/config"
|
||||
)
|
||||
|
||||
type (
|
||||
Dependencies interface {
|
||||
PersistenceProvider
|
||||
otelx.Provider
|
||||
logrusx.Provider
|
||||
ConfigProvider
|
||||
httpx.ClientProvider
|
||||
jsonnetsecure.VMProvider
|
||||
}
|
||||
|
||||
Courier interface {
|
||||
Work(ctx context.Context) error
|
||||
QueueEmail(ctx context.Context, t EmailTemplate) (uuid.UUID, error)
|
||||
QueueSMS(ctx context.Context, t SMSTemplate) (uuid.UUID, error)
|
||||
DispatchQueue(ctx context.Context) error
|
||||
DispatchMessage(ctx context.Context, msg Message) error
|
||||
UseBackoff(b backoff.BackOff)
|
||||
FailOnDispatchError()
|
||||
}
|
||||
|
||||
Provider interface {
|
||||
Courier(ctx context.Context) (Courier, error)
|
||||
}
|
||||
|
||||
ConfigProvider interface {
|
||||
CourierConfig() config.CourierConfigs
|
||||
}
|
||||
|
||||
courier struct {
|
||||
deps Dependencies
|
||||
failOnDispatchError bool
|
||||
backoff backoff.BackOff
|
||||
newEmailTemplateFromMessage func(d template.Dependencies, msg Message) (EmailTemplate, error)
|
||||
}
|
||||
)
|
||||
|
||||
func NewCourier(ctx context.Context, deps Dependencies) (Courier, error) {
|
||||
return NewCourierWithCustomTemplates(ctx, deps, NewEmailTemplateFromMessage)
|
||||
}
|
||||
|
||||
func NewCourierWithCustomTemplates(_ context.Context, deps Dependencies, newEmailTemplateFromMessage func(d template.Dependencies, msg Message) (EmailTemplate, error)) (Courier, error) {
|
||||
return &courier{
|
||||
deps: deps,
|
||||
backoff: backoff.NewExponentialBackOff(),
|
||||
newEmailTemplateFromMessage: newEmailTemplateFromMessage,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (c *courier) FailOnDispatchError() {
|
||||
c.failOnDispatchError = true
|
||||
}
|
||||
|
||||
func (c *courier) Work(ctx context.Context) error {
|
||||
errChan := make(chan error)
|
||||
defer close(errChan)
|
||||
|
||||
go c.watchMessages(ctx, errChan)
|
||||
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
if errors.Is(ctx.Err(), context.Canceled) {
|
||||
return nil
|
||||
}
|
||||
return ctx.Err()
|
||||
case err := <-errChan:
|
||||
return errors.WithStack(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (c *courier) UseBackoff(b backoff.BackOff) {
|
||||
c.backoff = b
|
||||
}
|
||||
|
||||
func (c *courier) watchMessages(ctx context.Context, errChan chan error) {
|
||||
wait := c.deps.CourierConfig().CourierWorkerPullWait(ctx)
|
||||
c.backoff.Reset()
|
||||
for {
|
||||
if err := backoff.Retry(func() error {
|
||||
return c.DispatchQueue(ctx)
|
||||
}, c.backoff); err != nil {
|
||||
errChan <- errors.WithStack(err)
|
||||
return
|
||||
}
|
||||
time.Sleep(wait)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user