86 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			86 lines
		
	
	
		
			1.5 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
 | 
						|
		ticker := time.NewTicker(s.Interval)
 | 
						|
		defer ticker.Stop()
 | 
						|
		for t := range ticker.C {
 | 
						|
			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
 | 
						|
	}
 | 
						|
}
 |