github.com/goravel/framework@v1.13.9/queue/task.go (about)

     1  package queue
     2  
     3  import (
     4  	"errors"
     5  	"time"
     6  
     7  	"github.com/RichardKnop/machinery/v2"
     8  	"github.com/RichardKnop/machinery/v2/tasks"
     9  
    10  	"github.com/goravel/framework/contracts/log"
    11  	"github.com/goravel/framework/contracts/queue"
    12  )
    13  
    14  type Task struct {
    15  	config     *Config
    16  	connection string
    17  	chain      bool
    18  	delay      *time.Time
    19  	machinery  *Machinery
    20  	jobs       []queue.Jobs
    21  	queue      string
    22  	server     *machinery.Server
    23  }
    24  
    25  func NewTask(config *Config, log log.Log, job queue.Job, args []queue.Arg) *Task {
    26  	return &Task{
    27  		config:     config,
    28  		connection: config.DefaultConnection(),
    29  		machinery:  NewMachinery(config, log),
    30  		jobs: []queue.Jobs{
    31  			{
    32  				Job:  job,
    33  				Args: args,
    34  			},
    35  		},
    36  	}
    37  }
    38  
    39  func NewChainTask(config *Config, log log.Log, jobs []queue.Jobs) *Task {
    40  	return &Task{
    41  		config:     config,
    42  		connection: config.DefaultConnection(),
    43  		chain:      true,
    44  		machinery:  NewMachinery(config, log),
    45  		jobs:       jobs,
    46  	}
    47  }
    48  
    49  func (receiver *Task) Delay(delay time.Time) queue.Task {
    50  	receiver.delay = &delay
    51  
    52  	return receiver
    53  }
    54  
    55  func (receiver *Task) Dispatch() error {
    56  	driver := receiver.config.Driver(receiver.connection)
    57  	if driver == "" {
    58  		return errors.New("unknown queue driver")
    59  	}
    60  	if driver == DriverSync || driver == "" {
    61  		return receiver.DispatchSync()
    62  	}
    63  
    64  	server, err := receiver.machinery.Server(receiver.connection, receiver.queue)
    65  	if err != nil {
    66  		return err
    67  	}
    68  
    69  	receiver.server = server
    70  
    71  	if receiver.chain {
    72  		return receiver.handleChain(receiver.jobs)
    73  	} else {
    74  		job := receiver.jobs[0]
    75  
    76  		return receiver.handleAsync(job.Job, job.Args)
    77  	}
    78  }
    79  
    80  func (receiver *Task) DispatchSync() error {
    81  	if receiver.chain {
    82  		for _, job := range receiver.jobs {
    83  			if err := receiver.handleSync(job.Job, job.Args); err != nil {
    84  				return err
    85  			}
    86  		}
    87  
    88  		return nil
    89  	} else {
    90  		job := receiver.jobs[0]
    91  
    92  		return receiver.handleSync(job.Job, job.Args)
    93  	}
    94  }
    95  
    96  func (receiver *Task) OnConnection(connection string) queue.Task {
    97  	receiver.connection = connection
    98  
    99  	return receiver
   100  }
   101  
   102  func (receiver *Task) OnQueue(queue string) queue.Task {
   103  	receiver.queue = receiver.config.Queue(receiver.connection, queue)
   104  
   105  	return receiver
   106  }
   107  
   108  func (receiver *Task) handleChain(jobs []queue.Jobs) error {
   109  	var signatures []*tasks.Signature
   110  	for _, job := range jobs {
   111  		var realArgs []tasks.Arg
   112  		for _, arg := range job.Args {
   113  			realArgs = append(realArgs, tasks.Arg{
   114  				Type:  arg.Type,
   115  				Value: arg.Value,
   116  			})
   117  		}
   118  
   119  		signatures = append(signatures, &tasks.Signature{
   120  			Name: job.Job.Signature(),
   121  			Args: realArgs,
   122  			ETA:  receiver.delay,
   123  		})
   124  	}
   125  
   126  	chain, err := tasks.NewChain(signatures...)
   127  	if err != nil {
   128  		return err
   129  	}
   130  
   131  	_, err = receiver.server.SendChain(chain)
   132  
   133  	return err
   134  }
   135  
   136  func (receiver *Task) handleAsync(job queue.Job, args []queue.Arg) error {
   137  	var realArgs []tasks.Arg
   138  	for _, arg := range args {
   139  		realArgs = append(realArgs, tasks.Arg{
   140  			Type:  arg.Type,
   141  			Value: arg.Value,
   142  		})
   143  	}
   144  
   145  	_, err := receiver.server.SendTask(&tasks.Signature{
   146  		Name: job.Signature(),
   147  		Args: realArgs,
   148  		ETA:  receiver.delay,
   149  	})
   150  	if err != nil {
   151  		return err
   152  	}
   153  
   154  	return nil
   155  }
   156  
   157  func (receiver *Task) handleSync(job queue.Job, args []queue.Arg) error {
   158  	var realArgs []any
   159  	for _, arg := range args {
   160  		realArgs = append(realArgs, arg.Value)
   161  	}
   162  
   163  	return job.Handle(realArgs...)
   164  }