github.com/gogf/gf@v1.16.9/os/gcron/gcron_cron.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  	"time"
    11  
    12  	"github.com/gogf/gf/container/garray"
    13  	"github.com/gogf/gf/container/gmap"
    14  	"github.com/gogf/gf/container/gtype"
    15  	"github.com/gogf/gf/os/glog"
    16  	"github.com/gogf/gf/os/gtimer"
    17  )
    18  
    19  type Cron struct {
    20  	idGen   *gtype.Int64    // Used for unique name generation.
    21  	status  *gtype.Int      // Timed task status(0: Not Start; 1: Running; 2: Stopped; -1: Closed)
    22  	entries *gmap.StrAnyMap // All timed task entries.
    23  	logger  *glog.Logger    // Logger, it is nil in default.
    24  
    25  	// Logging path(folder).
    26  	// Deprecated, use logger instead.
    27  	logPath *gtype.String
    28  
    29  	// Logging level.
    30  	// Deprecated, use logger instead.
    31  	logLevel *gtype.Int
    32  }
    33  
    34  // New returns a new Cron object with default settings.
    35  func New() *Cron {
    36  	return &Cron{
    37  		idGen:    gtype.NewInt64(),
    38  		status:   gtype.NewInt(StatusRunning),
    39  		entries:  gmap.NewStrAnyMap(true),
    40  		logPath:  gtype.NewString(),
    41  		logLevel: gtype.NewInt(glog.LEVEL_PROD),
    42  	}
    43  }
    44  
    45  // SetLogger sets the logger for cron.
    46  func (c *Cron) SetLogger(logger *glog.Logger) {
    47  	c.logger = logger
    48  }
    49  
    50  // GetLogger returns the logger in the cron.
    51  func (c *Cron) GetLogger() *glog.Logger {
    52  	return c.logger
    53  }
    54  
    55  // SetLogPath sets the logging folder path.
    56  // Deprecated, use SetLogger instead.
    57  func (c *Cron) SetLogPath(path string) {
    58  	c.logPath.Set(path)
    59  }
    60  
    61  // GetLogPath return the logging folder path.
    62  // Deprecated, use GetLogger instead.
    63  func (c *Cron) GetLogPath() string {
    64  	return c.logPath.Val()
    65  }
    66  
    67  // SetLogLevel sets the logging level.
    68  // Deprecated, use SetLogger instead.
    69  func (c *Cron) SetLogLevel(level int) {
    70  	c.logLevel.Set(level)
    71  }
    72  
    73  // GetLogLevel returns the logging level.
    74  // Deprecated, use GetLogger instead.
    75  func (c *Cron) GetLogLevel() int {
    76  	return c.logLevel.Val()
    77  }
    78  
    79  // AddEntry creates and returns a new Entry object.
    80  func (c *Cron) AddEntry(pattern string, job func(), times int, singleton bool, name ...string) (*Entry, error) {
    81  	var (
    82  		entryName = ""
    83  		infinite  = false
    84  	)
    85  	if len(name) > 0 {
    86  		entryName = name[0]
    87  	}
    88  	if times <= 0 {
    89  		infinite = true
    90  	}
    91  	return c.doAddEntry(addEntryInput{
    92  		Name:      entryName,
    93  		Job:       job,
    94  		Times:     times,
    95  		Pattern:   pattern,
    96  		Singleton: singleton,
    97  		Infinite:  infinite,
    98  	})
    99  }
   100  
   101  // Add adds a timed task.
   102  // A unique `name` can be bound with the timed task.
   103  // It returns and error if the `name` is already used.
   104  func (c *Cron) Add(pattern string, job func(), name ...string) (*Entry, error) {
   105  	return c.AddEntry(pattern, job, -1, false, name...)
   106  }
   107  
   108  // AddSingleton adds a singleton timed task.
   109  // A singleton timed task is that can only be running one single instance at the same time.
   110  // A unique `name` can be bound with the timed task.
   111  // It returns and error if the `name` is already used.
   112  func (c *Cron) AddSingleton(pattern string, job func(), name ...string) (*Entry, error) {
   113  	return c.AddEntry(pattern, job, -1, true, name...)
   114  }
   115  
   116  // AddTimes adds a timed task which can be run specified times.
   117  // A unique `name` can be bound with the timed task.
   118  // It returns and error if the `name` is already used.
   119  func (c *Cron) AddTimes(pattern string, times int, job func(), name ...string) (*Entry, error) {
   120  	return c.AddEntry(pattern, job, times, false, name...)
   121  }
   122  
   123  // AddOnce adds a timed task which can be run only once.
   124  // A unique `name` can be bound with the timed task.
   125  // It returns and error if the `name` is already used.
   126  func (c *Cron) AddOnce(pattern string, job func(), name ...string) (*Entry, error) {
   127  	return c.AddEntry(pattern, job, 1, false, name...)
   128  }
   129  
   130  // DelayAddEntry adds a timed task after `delay` time.
   131  func (c *Cron) DelayAddEntry(delay time.Duration, pattern string, job func(), times int, singleton bool, name ...string) {
   132  	gtimer.AddOnce(delay, func() {
   133  		if _, err := c.AddEntry(pattern, job, times, singleton, name...); err != nil {
   134  			panic(err)
   135  		}
   136  	})
   137  }
   138  
   139  // DelayAdd adds a timed task after `delay` time.
   140  func (c *Cron) DelayAdd(delay time.Duration, pattern string, job func(), name ...string) {
   141  	gtimer.AddOnce(delay, func() {
   142  		if _, err := c.Add(pattern, job, name...); err != nil {
   143  			panic(err)
   144  		}
   145  	})
   146  }
   147  
   148  // DelayAddSingleton adds a singleton timed task after `delay` time.
   149  func (c *Cron) DelayAddSingleton(delay time.Duration, pattern string, job func(), name ...string) {
   150  	gtimer.AddOnce(delay, func() {
   151  		if _, err := c.AddSingleton(pattern, job, name...); err != nil {
   152  			panic(err)
   153  		}
   154  	})
   155  }
   156  
   157  // DelayAddOnce adds a timed task after `delay` time.
   158  // This timed task can be run only once.
   159  func (c *Cron) DelayAddOnce(delay time.Duration, pattern string, job func(), name ...string) {
   160  	gtimer.AddOnce(delay, func() {
   161  		if _, err := c.AddOnce(pattern, job, name...); err != nil {
   162  			panic(err)
   163  		}
   164  	})
   165  }
   166  
   167  // DelayAddTimes adds a timed task after `delay` time.
   168  // This timed task can be run specified times.
   169  func (c *Cron) DelayAddTimes(delay time.Duration, pattern string, times int, job func(), name ...string) {
   170  	gtimer.AddOnce(delay, func() {
   171  		if _, err := c.AddTimes(pattern, times, job, name...); err != nil {
   172  			panic(err)
   173  		}
   174  	})
   175  }
   176  
   177  // Search returns a scheduled task with the specified `name`.
   178  // It returns nil if not found.
   179  func (c *Cron) Search(name string) *Entry {
   180  	if v := c.entries.Get(name); v != nil {
   181  		return v.(*Entry)
   182  	}
   183  	return nil
   184  }
   185  
   186  // Start starts running the specified timed task named `name`.
   187  // If no`name` specified, it starts the entire cron.
   188  func (c *Cron) Start(name ...string) {
   189  	if len(name) > 0 {
   190  		for _, v := range name {
   191  			if entry := c.Search(v); entry != nil {
   192  				entry.Start()
   193  			}
   194  		}
   195  	} else {
   196  		c.status.Set(StatusReady)
   197  	}
   198  }
   199  
   200  // Stop stops running the specified timed task named `name`.
   201  // If no`name` specified, it stops the entire cron.
   202  func (c *Cron) Stop(name ...string) {
   203  	if len(name) > 0 {
   204  		for _, v := range name {
   205  			if entry := c.Search(v); entry != nil {
   206  				entry.Stop()
   207  			}
   208  		}
   209  	} else {
   210  		c.status.Set(StatusStopped)
   211  	}
   212  }
   213  
   214  // Remove deletes scheduled task which named `name`.
   215  func (c *Cron) Remove(name string) {
   216  	if v := c.entries.Get(name); v != nil {
   217  		v.(*Entry).Close()
   218  	}
   219  }
   220  
   221  // Close stops and closes current cron.
   222  func (c *Cron) Close() {
   223  	c.status.Set(StatusClosed)
   224  }
   225  
   226  // Size returns the size of the timed tasks.
   227  func (c *Cron) Size() int {
   228  	return c.entries.Size()
   229  }
   230  
   231  // Entries return all timed tasks as slice(order by registered time asc).
   232  func (c *Cron) Entries() []*Entry {
   233  	array := garray.NewSortedArraySize(c.entries.Size(), func(v1, v2 interface{}) int {
   234  		entry1 := v1.(*Entry)
   235  		entry2 := v2.(*Entry)
   236  		if entry1.Time.Nanosecond() > entry2.Time.Nanosecond() {
   237  			return 1
   238  		}
   239  		return -1
   240  	}, true)
   241  	c.entries.RLockFunc(func(m map[string]interface{}) {
   242  		for _, v := range m {
   243  			array.Add(v.(*Entry))
   244  		}
   245  	})
   246  	entries := make([]*Entry, array.Len())
   247  	array.RLockFunc(func(array []interface{}) {
   248  		for k, v := range array {
   249  			entries[k] = v.(*Entry)
   250  		}
   251  	})
   252  	return entries
   253  }