...

Source file src/github.com/chaos-mesh/chaos-mesh/controllers/schedule/cron/utils.go

Documentation: github.com/chaos-mesh/chaos-mesh/controllers/schedule/cron

     1  // Copyright 2021 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  // http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  package cron
    17  
    18  import (
    19  	"time"
    20  
    21  	"github.com/pkg/errors"
    22  
    23  	"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
    24  )
    25  
    26  // Get this function from Kubernetes
    27  
    28  // getRecentUnmetScheduleTime gets the most recent time that have passed when a Job should have started but did not.
    29  //
    30  // If there are too many (>100) unstarted times, just give up and return a nil.
    31  func getRecentUnmetScheduleTime(schedule *v1alpha1.Schedule, now time.Time) (*time.Time, *time.Time, error) {
    32  	sched, err := v1alpha1.StandardCronParser.Parse(schedule.Spec.Schedule)
    33  	if err != nil {
    34  		return nil, nil, errors.Errorf("unparseable schedule: %s : %s", schedule.Spec.Schedule, err)
    35  	}
    36  
    37  	var earliestTime time.Time
    38  	if !schedule.Status.LastScheduleTime.UTC().IsZero() {
    39  		earliestTime = schedule.Status.LastScheduleTime.Time
    40  	} else {
    41  		earliestTime = schedule.ObjectMeta.CreationTimestamp.Time
    42  	}
    43  	if schedule.Spec.StartingDeadlineSeconds != nil {
    44  		schedulingDeadline := now.Add(-time.Second * time.Duration(*schedule.Spec.StartingDeadlineSeconds))
    45  
    46  		if schedulingDeadline.After(earliestTime) {
    47  			earliestTime = schedulingDeadline
    48  		}
    49  	}
    50  	if earliestTime.After(now) {
    51  		return nil, nil, errors.Errorf("earliestTime is later than now: earliestTime: %v, now: %v", earliestTime, now)
    52  	}
    53  
    54  	iterateTime := 0
    55  	var missedRun *time.Time
    56  	nextRun := sched.Next(earliestTime)
    57  	for t := sched.Next(earliestTime); !t.After(now); t = sched.Next(t) {
    58  		t := t
    59  
    60  		missedRun = &t
    61  		nextRun = sched.Next(*missedRun)
    62  
    63  		iterateTime++
    64  		if iterateTime > 100 {
    65  			// We can't get the most recent times so just return an empty slice
    66  			return nil, nil, errors.New("too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew")
    67  		}
    68  	}
    69  
    70  	return missedRun, &nextRun, nil
    71  }
    72