84 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			84 lines
		
	
	
		
			1.4 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Package task provides an interface for distributed jobs
 | |
| package task
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| 	"time"
 | |
| )
 | |
| 
 | |
| // Task represents a distributed task
 | |
| type Task interface {
 | |
| 	// Run runs a command immediately until completion
 | |
| 	Run(Command) error
 | |
| 	// Status provides status of last execution
 | |
| 	Status() string
 | |
| }
 | |
| 
 | |
| // Command to be executed
 | |
| type Command struct {
 | |
| 	Name string
 | |
| 	Func func() error
 | |
| }
 | |
| 
 | |
| // Schedule represents a time or interval at which a task should run
 | |
| type Schedule struct {
 | |
| 	// When to start the schedule. Zero time means immediately
 | |
| 	Time time.Time
 | |
| 	// Non zero interval dictates an ongoing schedule
 | |
| 	Interval time.Duration
 | |
| }
 | |
| 
 | |
| type Options struct {
 | |
| 	// Pool size for workers
 | |
| 	Pool int
 | |
| 	// Alternative options
 | |
| 	Context context.Context
 | |
| }
 | |
| 
 | |
| type Option func(o *Options)
 | |
| 
 | |
| func (c Command) Execute() error {
 | |
| 	return c.Func()
 | |
| }
 | |
| 
 | |
| func (c Command) String() string {
 | |
| 	return c.Name
 | |
| }
 | |
| 
 | |
| func (s Schedule) Run() <-chan time.Time {
 | |
| 	d := s.Time.Sub(time.Now())
 | |
| 
 | |
| 	ch := make(chan time.Time, 1)
 | |
| 
 | |
| 	go func() {
 | |
| 		// wait for start time
 | |
| 		<-time.After(d)
 | |
| 
 | |
| 		// zero interval
 | |
| 		if s.Interval == time.Duration(0) {
 | |
| 			ch <- time.Now()
 | |
| 			close(ch)
 | |
| 			return
 | |
| 		}
 | |
| 
 | |
| 		// start ticker
 | |
| 		for t := range time.Tick(s.Interval) {
 | |
| 			ch <- t
 | |
| 		}
 | |
| 	}()
 | |
| 
 | |
| 	return ch
 | |
| }
 | |
| 
 | |
| func (s Schedule) String() string {
 | |
| 	return fmt.Sprintf("%d-%d", s.Time.Unix(), s.Interval)
 | |
| }
 | |
| 
 | |
| // WithPool sets the pool size for concurrent work
 | |
| func WithPool(i int) Option {
 | |
| 	return func(o *Options) {
 | |
| 		o.Pool = i
 | |
| 	}
 | |
| }
 |