git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/queue/queue.go (about) 1 package queue 2 3 import ( 4 "context" 5 "encoding/json" 6 "time" 7 8 "git.sr.ht/~pingoo/stdx/db" 9 "git.sr.ht/~pingoo/stdx/guid" 10 ) 11 12 // TODO: detect job that have expired (timeout) 13 type RetryStrategy int32 14 type JobStatus int32 15 16 const ( 17 MinRetryMax int64 = 0 18 MaxRetryMax int64 = 100 19 DefaultRetryMax int64 = 5 20 21 MinRetryDelay int64 = 1 22 MaxRetryDelay int64 = 86_400 23 DefaultRetryDelay int64 = 5 24 25 DefaultRetryStrategy = RetryStrategyConstant 26 27 MinTimeout int64 = 1 28 MaxTimeout int64 = 7200 29 DefaultTimeout int64 = 60 30 31 RetryStrategyConstant RetryStrategy = 0 32 RetryStrategyExponential RetryStrategy = 1 33 34 JobStatusQueued JobStatus = 0 35 JobStatusRunning JobStatus = 1 36 JobStatusFailed JobStatus = 2 37 ) 38 39 type Queue interface { 40 Push(ctx context.Context, tx db.Queryer, newJob NewJobInput) error 41 // pull fetches at most `number_of_jobs` from the queue. 42 Pull(ctx context.Context, numberOfJobs int64) ([]Job, error) 43 DeleteJob(ctx context.Context, jobID guid.GUID) error 44 FailJob(ctx context.Context, job Job) error 45 Clear(ctx context.Context) error 46 Stop(ctx context.Context) 47 } 48 49 type NewJobInput struct { 50 Type string 51 Data any 52 53 // ScheduledFor is the date when the job should be scheduled for 54 // now() if empty 55 ScheduledFor *time.Time 56 57 // RetryMax is the max number of times a job should be retried 58 // 0-100 59 // default: 5 60 RetryMax *int64 61 62 // RetryDelay is the number of seconds between 2 retry attempts 63 // 1-86400 64 // default: 5 65 RetryDelay *int64 66 67 // constant, exponential 68 // default: Constant 69 RetryStrategy RetryStrategy 70 71 // 1-7200 72 // default: 60 73 Timeout *int64 74 } 75 76 type Job struct { 77 ID guid.GUID `db:"id"` 78 CreatedAt time.Time `db:"created_at"` 79 UpdatedAt time.Time `db:"updated_at"` 80 ScheduledFor time.Time `db:"scheduled_for"` 81 FailedAttempts int64 `db:"failed_attempts"` 82 // priority: i64, 83 Status JobStatus `db:"status"` 84 Type string `db:"type"` 85 RawData json.RawMessage `db:"data"` 86 RetryMax int64 `db:"retry_max"` 87 RetryDelay int64 `db:"retry_delay"` 88 RetryStrategy RetryStrategy `db:"retry_strategy"` 89 Timeout int64 `db:"timeout"` 90 } 91 92 func (job *Job) GetData(data any) (err error) { 93 err = json.Unmarshal(job.RawData, &data) 94 if err != nil { 95 return 96 } 97 98 return 99 }