github.com/gogf/gf/v2@v2.7.4/os/gcron/gcron_schedule_check.go (about)

     1  // Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
     2  //
     3  // This Source Code Form is subject to the terms of the MIT License.
     4  // If a copy of the MIT was not distributed with this file,
     5  // You can obtain one at https://github.com/gogf/gf.
     6  
     7  package gcron
     8  
     9  import (
    10  	"context"
    11  	"time"
    12  
    13  	"github.com/gogf/gf/v2/os/gtime"
    14  )
    15  
    16  // checkMeetAndUpdateLastSeconds checks if the given time `t` meets the runnable point for the job.
    17  // This function is called every second.
    18  func (s *cronSchedule) checkMeetAndUpdateLastSeconds(ctx context.Context, currentTime time.Time) (ok bool) {
    19  	var (
    20  		lastCheckTimestamp = s.getAndUpdateLastCheckTimestamp(ctx, currentTime)
    21  		lastCheckTime      = gtime.NewFromTimeStamp(lastCheckTimestamp)
    22  		lastMeetTime       = gtime.NewFromTimeStamp(s.lastMeetTimestamp.Val())
    23  	)
    24  	defer func() {
    25  		if ok {
    26  			s.lastMeetTimestamp.Set(currentTime.Unix())
    27  		}
    28  	}()
    29  	if !s.checkMinIntervalAndItemMapMeet(lastMeetTime.Time, lastCheckTime.Time, currentTime) {
    30  		return false
    31  	}
    32  	return true
    33  }
    34  
    35  func (s *cronSchedule) checkMinIntervalAndItemMapMeet(
    36  	lastMeetTime, lastCheckTime, currentTime time.Time,
    37  ) (ok bool) {
    38  	if s.everySeconds != 0 {
    39  		// It checks using interval.
    40  		secondsAfterCreated := lastCheckTime.UnixNano()/1e9 - s.createTimestamp
    41  		if secondsAfterCreated > 0 {
    42  			return secondsAfterCreated%s.everySeconds == 0
    43  		}
    44  		return false
    45  	}
    46  	if !s.checkMeetSecond(lastMeetTime, currentTime) {
    47  		return false
    48  	}
    49  	if !s.checkMeetMinute(currentTime) {
    50  		return false
    51  	}
    52  	if !s.checkMeetHour(currentTime) {
    53  		return false
    54  	}
    55  	if !s.checkMeetDay(currentTime) {
    56  		return false
    57  	}
    58  	if !s.checkMeetMonth(currentTime) {
    59  		return false
    60  	}
    61  	if !s.checkMeetWeek(currentTime) {
    62  		return false
    63  	}
    64  	return true
    65  }
    66  
    67  func (s *cronSchedule) checkMeetSecond(lastMeetTime, currentTime time.Time) (ok bool) {
    68  	if s.ignoreSeconds {
    69  		if currentTime.Unix()-lastMeetTime.Unix() < 60 {
    70  			return false
    71  		}
    72  	} else {
    73  		// If this pattern is set in precise second time,
    74  		// it is not allowed executed in the same time.
    75  		if len(s.secondMap) == 1 && lastMeetTime.Format(time.RFC3339) == currentTime.Format(time.RFC3339) {
    76  			return false
    77  		}
    78  		if !s.keyMatch(s.secondMap, currentTime.Second()) {
    79  			return false
    80  		}
    81  	}
    82  	return true
    83  }
    84  
    85  func (s *cronSchedule) checkMeetMinute(currentTime time.Time) (ok bool) {
    86  	if !s.keyMatch(s.minuteMap, currentTime.Minute()) {
    87  		return false
    88  	}
    89  	return true
    90  }
    91  
    92  func (s *cronSchedule) checkMeetHour(currentTime time.Time) (ok bool) {
    93  	if !s.keyMatch(s.hourMap, currentTime.Hour()) {
    94  		return false
    95  	}
    96  	return true
    97  }
    98  
    99  func (s *cronSchedule) checkMeetDay(currentTime time.Time) (ok bool) {
   100  	if !s.keyMatch(s.dayMap, currentTime.Day()) {
   101  		return false
   102  	}
   103  	return true
   104  }
   105  
   106  func (s *cronSchedule) checkMeetMonth(currentTime time.Time) (ok bool) {
   107  	if !s.keyMatch(s.monthMap, int(currentTime.Month())) {
   108  		return false
   109  	}
   110  	return true
   111  }
   112  
   113  func (s *cronSchedule) checkMeetWeek(currentTime time.Time) (ok bool) {
   114  	if !s.keyMatch(s.weekMap, int(currentTime.Weekday())) {
   115  		return false
   116  	}
   117  	return true
   118  }
   119  
   120  func (s *cronSchedule) keyMatch(m map[int]struct{}, key int) bool {
   121  	_, ok := m[key]
   122  	return ok
   123  }
   124  
   125  func (s *cronSchedule) checkItemMapMeet(lastMeetTime, currentTime time.Time) (ok bool) {
   126  	// second.
   127  	if s.ignoreSeconds {
   128  		if currentTime.Unix()-lastMeetTime.Unix() < 60 {
   129  			return false
   130  		}
   131  	} else {
   132  		if !s.keyMatch(s.secondMap, currentTime.Second()) {
   133  			return false
   134  		}
   135  	}
   136  	// minute.
   137  	if !s.keyMatch(s.minuteMap, currentTime.Minute()) {
   138  		return false
   139  	}
   140  	// hour.
   141  	if !s.keyMatch(s.hourMap, currentTime.Hour()) {
   142  		return false
   143  	}
   144  	// day.
   145  	if !s.keyMatch(s.dayMap, currentTime.Day()) {
   146  		return false
   147  	}
   148  	// month.
   149  	if !s.keyMatch(s.monthMap, int(currentTime.Month())) {
   150  		return false
   151  	}
   152  	// week.
   153  	if !s.keyMatch(s.weekMap, int(currentTime.Weekday())) {
   154  		return false
   155  	}
   156  	return true
   157  }