A retry after a failed attachment or a failed CompleteJob created another task for the same report. The task id is now stored as soon as the task is created, a retry with a stored id only re-attempts the attachment, a sent submission with a task id is skipped, and a CompleteJob failure is logged instead of returned.
59 lines
2.0 KiB
Go
59 lines
2.0 KiB
Go
package feedback
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"log/slog"
|
|
|
|
"git.golem15.com/golem15/sm-feedback-plugin/classes"
|
|
"git.golem15.com/golem15/summercms/modules/conga"
|
|
"git.golem15.com/golem15/summercms/modules/pact"
|
|
"gocloud.dev/blob"
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
var _ pact.HasJobs = (*Plugin)(nil)
|
|
|
|
// Jobs registers the G15Office sync worker on the feedback queue, with
|
|
// SyncFeedbackToG15Office::$tries attempts (River's backoff replaces PHP's
|
|
// fixed 30 s between them).
|
|
func (p *Plugin) Jobs() []pact.Job {
|
|
return []pact.Job{
|
|
conga.Job(p.syncG15Office, conga.OnQueue(classes.SyncG15OfficeQueue), conga.MaxAttempts(3)),
|
|
}
|
|
}
|
|
|
|
// syncG15Office resolves the app services per run (Boot runs before serve
|
|
// publishes the database), files the submission and completes its
|
|
// summer_jobs row. The submission's content, the token and the URLs are
|
|
// never logged; only the submission id is.
|
|
func (p *Plugin) syncG15Office(ctx context.Context, args classes.SyncG15OfficeArgs) error {
|
|
if p.app == nil {
|
|
return errors.New("feedback: app is not booted")
|
|
}
|
|
gdb, ok := p.app.Lookup[*gorm.DB]()
|
|
if !ok || gdb == nil {
|
|
return errors.New("feedback: database is not published")
|
|
}
|
|
bucket, _ := p.app.Lookup[*blob.Bucket]()
|
|
err := classes.SyncG15Office(ctx, classes.SyncDeps{
|
|
DB: gdb,
|
|
Bucket: bucket,
|
|
Client: classes.NewG15OfficeClient(p.app.Config),
|
|
}, args)
|
|
if err != nil {
|
|
slog.Default().Warn("golem15.feedback: filing a submission in G15Office failed", slog.Uint64("submission_id", uint64(args.SubmissionID)))
|
|
return err
|
|
}
|
|
// The task is filed: a failed completion is logged, not returned, so
|
|
// River does not retry a job whose side effect already happened.
|
|
if id, ok := conga.JobID(ctx); ok {
|
|
if m, err := conga.From(p.app); err == nil {
|
|
if err := m.CompleteJob(ctx, id, nil); err != nil {
|
|
slog.Default().Warn("golem15.feedback: completing the G15Office job failed", slog.Uint64("submission_id", uint64(args.SubmissionID)), slog.Uint64("job_id", uint64(id)))
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|