mirror of
				https://github.com/datarhei/core.git
				synced 2025-10-31 11:26:52 +08:00 
			
		
		
		
	 b63b23527b
			
		
	
	b63b23527b
	
	
	
		
			
			The scheduler allows to define when a process should run. It can be either a timestamp in RFC3339 format or a crontab expression. If a scheduler is given, reconnect and the reconnect delay will only apply to processes that exited as failed. The timeout allows to define when a process should be gracefully stopped. It is measured from the actual start of that process including all reconnects due to failures. If the process finished regularly, the timeout will be reset.
		
			
				
	
	
		
			70 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			70 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package process
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"time"
 | |
| 
 | |
| 	"github.com/adhocore/gronx"
 | |
| )
 | |
| 
 | |
| type Scheduler interface {
 | |
| 	// Next returns the duration until the next scheduled time in reference
 | |
| 	// to time.Npw(). If there's no next scheduled time, a negative duration
 | |
| 	// and an error will be returned.
 | |
| 	Next() (time.Duration, error)
 | |
| 
 | |
| 	// NextAfter returns the same as Next(), but with the given reference
 | |
| 	// time.
 | |
| 	NextAfter(after time.Time) (time.Duration, error)
 | |
| }
 | |
| 
 | |
| type scheduler struct {
 | |
| 	pattern string
 | |
| 	pit     time.Time
 | |
| 	isCron  bool
 | |
| }
 | |
| 
 | |
| func NewScheduler(pattern string) (Scheduler, error) {
 | |
| 	s := &scheduler{}
 | |
| 
 | |
| 	t, err := time.Parse(time.RFC3339, pattern)
 | |
| 	if err == nil {
 | |
| 		s.pit = t
 | |
| 		s.isCron = false
 | |
| 	} else {
 | |
| 		cron := gronx.New()
 | |
| 		if !cron.IsValid(pattern) {
 | |
| 			return nil, err
 | |
| 		}
 | |
| 		s.pattern = pattern
 | |
| 		s.isCron = true
 | |
| 	}
 | |
| 
 | |
| 	return s, nil
 | |
| }
 | |
| 
 | |
| func (s *scheduler) Next() (time.Duration, error) {
 | |
| 	return s.NextAfter(time.Now())
 | |
| }
 | |
| 
 | |
| func (s *scheduler) NextAfter(after time.Time) (time.Duration, error) {
 | |
| 	var t time.Time
 | |
| 	var err error
 | |
| 
 | |
| 	if s.isCron {
 | |
| 		t, err = gronx.NextTickAfter(s.pattern, after, false)
 | |
| 		if err != nil {
 | |
| 			return time.Duration(-1), fmt.Errorf("no next time has been scheduled")
 | |
| 		}
 | |
| 	} else {
 | |
| 		t = s.pit
 | |
| 	}
 | |
| 
 | |
| 	d := t.Sub(after)
 | |
| 	if d < time.Duration(0) {
 | |
| 		return d, fmt.Errorf("no next time has been scheduled")
 | |
| 	}
 | |
| 
 | |
| 	return d, nil
 | |
| }
 |