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  }