1
0
mirror of https://github.com/gogf/gf.git synced 2025-04-05 11:18:50 +08:00

add neccessary parameter context for package gcron/gtimer

This commit is contained in:
John Guo 2021-10-30 15:36:10 +08:00
parent 1188793f8f
commit 17e6063c5c
30 changed files with 365 additions and 268 deletions

View File

@ -8,6 +8,7 @@
package gpool
import (
"context"
"github.com/gogf/gf/v2/errors/gcode"
"github.com/gogf/gf/v2/errors/gerror"
"time"
@ -60,7 +61,7 @@ func New(ttl time.Duration, newFunc NewFunc, expireFunc ...ExpireFunc) *Pool {
if len(expireFunc) > 0 {
r.ExpireFunc = expireFunc[0]
}
gtimer.AddSingleton(time.Second, r.checkExpireItems)
gtimer.AddSingleton(context.Background(), time.Second, r.checkExpireItems)
return r
}
@ -134,7 +135,7 @@ func (p *Pool) Close() {
}
// checkExpire removes expired items from pool in every second.
func (p *Pool) checkExpireItems() {
func (p *Pool) checkExpireItems(ctx context.Context) {
if p.closed.Val() {
// If p has ExpireFunc,
// then it must close all items using this function.
@ -157,7 +158,7 @@ func (p *Pool) checkExpireItems() {
var latestExpire int64 = -1
// Retrieve the current timestamp in milliseconds, it expires the items
// by comparing with this timestamp. It is not accurate comparison for
// every items expired, but high performance.
// every item expired, but high performance.
var timestampMilli = gtime.TimestampMilli()
for {
if latestExpire > timestampMilli {

View File

@ -10,7 +10,6 @@ import (
"fmt"
"github.com/gogf/gf/v2/text/gstr"
"github.com/gogf/gf/v2/util/gconv"
"strings"
)
// Where sets the condition statement for the model. The parameter `where` can be type of
@ -266,55 +265,6 @@ func (m *Model) WhereOrNotNull(columns ...string) *Model {
return model
}
// Group sets the "GROUP BY" statement for the model.
func (m *Model) Group(groupBy ...string) *Model {
if len(groupBy) == 0 {
return m
}
model := m.getModel()
if model.groupBy != "" {
model.groupBy += ","
}
model.groupBy = model.db.GetCore().QuoteString(strings.Join(groupBy, ","))
return model
}
// Order sets the "ORDER BY" statement for the model.
func (m *Model) Order(orderBy ...string) *Model {
if len(orderBy) == 0 {
return m
}
model := m.getModel()
if model.orderBy != "" {
model.orderBy += ","
}
model.orderBy = model.db.GetCore().QuoteString(strings.Join(orderBy, " "))
return model
}
// OrderAsc sets the "ORDER BY xxx ASC" statement for the model.
func (m *Model) OrderAsc(column string) *Model {
if len(column) == 0 {
return m
}
return m.Order(column + " ASC")
}
// OrderDesc sets the "ORDER BY xxx DESC" statement for the model.
func (m *Model) OrderDesc(column string) *Model {
if len(column) == 0 {
return m
}
return m.Order(column + " DESC")
}
// OrderRandom sets the "ORDER BY RANDOM()" statement for the model.
func (m *Model) OrderRandom() *Model {
model := m.getModel()
model.orderBy = "RAND()"
return model
}
// Limit sets the "LIMIT" statement for the model.
// The parameter `limit` can be either one or two number, if passed two number is passed,
// it then sets "LIMIT limit[0],limit[1]" statement for the model, or else it sets "LIMIT limit[0]"

View File

@ -0,0 +1,63 @@
// Copyright GoFrame Author(https://goframe.org). All Rights Reserved.
//
// This Source Code Form is subject to the terms of the MIT License.
// If a copy of the MIT was not distributed with this file,
// You can obtain one at https://github.com/gogf/gf.
package gdb
import "strings"
// Order sets the "ORDER BY" statement for the model.
//
// Eg:
// Order("id desc")
// Order("id", "desc")
// Order("id desc,name asc")
func (m *Model) Order(orderBy ...string) *Model {
if len(orderBy) == 0 {
return m
}
model := m.getModel()
if model.orderBy != "" {
model.orderBy += ","
}
model.orderBy = model.db.GetCore().QuoteString(strings.Join(orderBy, " "))
return model
}
// OrderAsc sets the "ORDER BY xxx ASC" statement for the model.
func (m *Model) OrderAsc(column string) *Model {
if len(column) == 0 {
return m
}
return m.Order(column + " ASC")
}
// OrderDesc sets the "ORDER BY xxx DESC" statement for the model.
func (m *Model) OrderDesc(column string) *Model {
if len(column) == 0 {
return m
}
return m.Order(column + " DESC")
}
// OrderRandom sets the "ORDER BY RANDOM()" statement for the model.
func (m *Model) OrderRandom() *Model {
model := m.getModel()
model.orderBy = "RAND()"
return model
}
// Group sets the "GROUP BY" statement for the model.
func (m *Model) Group(groupBy ...string) *Model {
if len(groupBy) == 0 {
return m
}
model := m.getModel()
if model.groupBy != "" {
model.groupBy += ","
}
model.groupBy = model.db.GetCore().QuoteString(strings.Join(groupBy, ","))
return model
}

View File

@ -43,9 +43,14 @@ func MiddlewareClientTracing(c *Client, r *http.Request) (*ClientResponse, error
// MiddlewareServerTracing is a serer middleware that enables tracing feature using standards of OpenTelemetry.
func MiddlewareServerTracing(r *Request) {
tr := otel.GetTracerProvider().Tracer(tracingInstrumentName, trace.WithInstrumentationVersion(gf.VERSION))
ctx := otel.GetTextMapPropagator().Extract(r.Context(), propagation.HeaderCarrier(r.Header))
ctx, span := tr.Start(ctx, r.URL.String(), trace.WithSpanKind(trace.SpanKindServer))
var (
tr = otel.GetTracerProvider().Tracer(tracingInstrumentName, trace.WithInstrumentationVersion(gf.VERSION))
ctx, span = tr.Start(
otel.GetTextMapPropagator().Extract(r.Context(), propagation.HeaderCarrier(r.Header)),
r.URL.String(),
trace.WithSpanKind(trace.SpanKindServer),
)
)
defer span.End()
span.SetAttributes(gtrace.CommonLabels()...)

View File

@ -240,9 +240,9 @@ func (s *Server) Start() error {
// If this is a child process, it then notifies its parent exit.
if gproc.IsChild() {
gtimer.SetTimeout(time.Duration(s.config.GracefulTimeout)*time.Second, func() {
gtimer.SetTimeout(ctx, time.Duration(s.config.GracefulTimeout)*time.Second, func(ctx context.Context) {
if err := gproc.Send(gproc.PPid(), []byte("exit"), adminGProcCommGroup); err != nil {
intlog.Error(context.TODO(), "server error in process communication:", err)
intlog.Error(ctx, "server error in process communication:", err)
}
})
}

View File

@ -68,7 +68,7 @@ func (p *utilAdmin) Restart(r *Request) {
// Shutdown shuts down all the servers.
func (p *utilAdmin) Shutdown(r *Request) {
gtimer.SetTimeout(time.Second, func() {
gtimer.SetTimeout(r.Context(), time.Second, func(ctx context.Context) {
// It shuts down the server after 1 second, which is not triggered by system signal,
// to ensure the response successfully to the client.
_ = r.Server.Shutdown()

View File

@ -220,7 +220,7 @@ func restartWebServers(ctx context.Context, signal string, newExeFilePath ...str
} else {
// Controlled by web page.
// It should ensure the response wrote to client and then close all servers gracefully.
gtimer.SetTimeout(time.Second, func() {
gtimer.SetTimeout(ctx, time.Second, func(ctx context.Context) {
forceCloseWebServers(ctx)
if err := forkRestartProcess(ctx, newExeFilePath...); err != nil {
intlog.Error(ctx, err)
@ -252,7 +252,7 @@ func shutdownWebServers(ctx context.Context, signal ...string) {
allDoneChan <- struct{}{}
} else {
glog.Printf(ctx, "%d: server shutting down by api", gproc.Pid())
gtimer.SetTimeout(time.Second, func() {
gtimer.SetTimeout(ctx, time.Second, func(ctx context.Context) {
forceCloseWebServers(ctx)
allDoneChan <- struct{}{}
})

View File

@ -394,7 +394,7 @@ func (c *AdapterMemory) makeExpireKey(expire int64) int64 {
// 1. Asynchronously process the data in the event list,
// and synchronize the results to the `expireTimes` and `expireSets` properties.
// 2. Clean up the expired key-value pair data.
func (c *AdapterMemory) syncEventAndClearExpired() {
func (c *AdapterMemory) syncEventAndClearExpired(ctx context.Context) {
if c.closed.Val() {
gtimer.Exit()
return

View File

@ -7,6 +7,7 @@
package gcache
import (
"context"
"time"
"github.com/gogf/gf/v2/container/glist"
@ -34,7 +35,7 @@ func newMemCacheLru(cache *AdapterMemory) *adapterMemoryLru {
rawList: glist.New(true),
closed: gtype.NewBool(),
}
gtimer.AddSingleton(time.Second, lru.SyncAndClear)
gtimer.AddSingleton(context.Background(), time.Second, lru.SyncAndClear)
return lru
}
@ -80,7 +81,7 @@ func (lru *adapterMemoryLru) Pop() interface{} {
// SyncAndClear synchronizes the keys from `rawList` to `list` and `data`
// using Least Recently Used algorithm.
func (lru *adapterMemoryLru) SyncAndClear() {
func (lru *adapterMemoryLru) SyncAndClear(ctx context.Context) {
if lru.closed.Val() {
gtimer.Exit()
return
@ -89,7 +90,7 @@ func (lru *adapterMemoryLru) SyncAndClear() {
for {
if v := lru.rawList.PopFront(); v != nil {
// Deleting the key from list.
if v := lru.data.Get(v); v != nil {
if v = lru.data.Get(v); v != nil {
lru.list.Remove(v.(*glist.Element))
}
// Pushing key to the head of the list

View File

@ -30,7 +30,7 @@ func New(lruCap ...int) *Cache {
}
// Here may be a "timer leak" if adapter is manually changed from memory adapter.
// Do not worry about this, as adapter is less changed, and it does nothing if it's not used.
gtimer.AddSingleton(time.Second, memAdapter.syncEventAndClearExpired)
gtimer.AddSingleton(context.Background(), time.Second, memAdapter.syncEventAndClearExpired)
return c
}

View File

@ -8,6 +8,7 @@
package gcron
import (
"context"
"github.com/gogf/gf/v2/os/glog"
"time"
@ -39,52 +40,52 @@ func GetLogger() *glog.Logger {
// Add adds a timed task to default cron object.
// A unique `name` can be bound with the timed task.
// It returns and error if the `name` is already used.
func Add(pattern string, job func(), name ...string) (*Entry, error) {
return defaultCron.Add(pattern, job, name...)
func Add(ctx context.Context, pattern string, job JobFunc, name ...string) (*Entry, error) {
return defaultCron.Add(ctx, pattern, job, name...)
}
// AddSingleton adds a singleton timed task, to default cron object.
// A singleton timed task is that can only be running one single instance at the same time.
// A unique `name` can be bound with the timed task.
// It returns and error if the `name` is already used.
func AddSingleton(pattern string, job func(), name ...string) (*Entry, error) {
return defaultCron.AddSingleton(pattern, job, name...)
func AddSingleton(ctx context.Context, pattern string, job JobFunc, name ...string) (*Entry, error) {
return defaultCron.AddSingleton(ctx, pattern, job, name...)
}
// AddOnce adds a timed task which can be run only once, to default cron object.
// A unique `name` can be bound with the timed task.
// It returns and error if the `name` is already used.
func AddOnce(pattern string, job func(), name ...string) (*Entry, error) {
return defaultCron.AddOnce(pattern, job, name...)
func AddOnce(ctx context.Context, pattern string, job JobFunc, name ...string) (*Entry, error) {
return defaultCron.AddOnce(ctx, pattern, job, name...)
}
// AddTimes adds a timed task which can be run specified times, to default cron object.
// A unique `name` can be bound with the timed task.
// It returns and error if the `name` is already used.
func AddTimes(pattern string, times int, job func(), name ...string) (*Entry, error) {
return defaultCron.AddTimes(pattern, times, job, name...)
func AddTimes(ctx context.Context, pattern string, times int, job JobFunc, name ...string) (*Entry, error) {
return defaultCron.AddTimes(ctx, pattern, times, job, name...)
}
// DelayAdd adds a timed task to default cron object after `delay` time.
func DelayAdd(delay time.Duration, pattern string, job func(), name ...string) {
defaultCron.DelayAdd(delay, pattern, job, name...)
func DelayAdd(ctx context.Context, delay time.Duration, pattern string, job JobFunc, name ...string) {
defaultCron.DelayAdd(ctx, delay, pattern, job, name...)
}
// DelayAddSingleton adds a singleton timed task after `delay` time to default cron object.
func DelayAddSingleton(delay time.Duration, pattern string, job func(), name ...string) {
defaultCron.DelayAddSingleton(delay, pattern, job, name...)
func DelayAddSingleton(ctx context.Context, delay time.Duration, pattern string, job JobFunc, name ...string) {
defaultCron.DelayAddSingleton(ctx, delay, pattern, job, name...)
}
// DelayAddOnce adds a timed task after `delay` time to default cron object.
// This timed task can be run only once.
func DelayAddOnce(delay time.Duration, pattern string, job func(), name ...string) {
defaultCron.DelayAddOnce(delay, pattern, job, name...)
func DelayAddOnce(ctx context.Context, delay time.Duration, pattern string, job JobFunc, name ...string) {
defaultCron.DelayAddOnce(ctx, delay, pattern, job, name...)
}
// DelayAddTimes adds a timed task after `delay` time to default cron object.
// This timed task can be run specified times.
func DelayAddTimes(delay time.Duration, pattern string, times int, job func(), name ...string) {
defaultCron.DelayAddTimes(delay, pattern, times, job, name...)
func DelayAddTimes(ctx context.Context, delay time.Duration, pattern string, times int, job JobFunc, name ...string) {
defaultCron.DelayAddTimes(ctx, delay, pattern, times, job, name...)
}
// Search returns a scheduled task with the specified `name`.

View File

@ -7,6 +7,7 @@
package gcron
import (
"context"
"time"
"github.com/gogf/gf/v2/container/garray"
@ -43,7 +44,7 @@ func (c *Cron) GetLogger() *glog.Logger {
}
// AddEntry creates and returns a new Entry object.
func (c *Cron) AddEntry(pattern string, job func(), times int, singleton bool, name ...string) (*Entry, error) {
func (c *Cron) AddEntry(ctx context.Context, pattern string, job JobFunc, times int, isSingleton bool, name ...string) (*Entry, error) {
var (
entryName = ""
infinite = false
@ -54,67 +55,68 @@ func (c *Cron) AddEntry(pattern string, job func(), times int, singleton bool, n
if times <= 0 {
infinite = true
}
return c.doAddEntry(addEntryInput{
Name: entryName,
Job: job,
Times: times,
Pattern: pattern,
Singleton: singleton,
Infinite: infinite,
return c.doAddEntry(doAddEntryInput{
Name: entryName,
Job: job,
Ctx: ctx,
Times: times,
Pattern: pattern,
IsSingleton: isSingleton,
Infinite: infinite,
})
}
// Add adds a timed task.
// A unique `name` can be bound with the timed task.
// It returns and error if the `name` is already used.
func (c *Cron) Add(pattern string, job func(), name ...string) (*Entry, error) {
return c.AddEntry(pattern, job, -1, false, name...)
func (c *Cron) Add(ctx context.Context, pattern string, job JobFunc, name ...string) (*Entry, error) {
return c.AddEntry(ctx, pattern, job, -1, false, name...)
}
// AddSingleton adds a singleton timed task.
// A singleton timed task is that can only be running one single instance at the same time.
// A unique `name` can be bound with the timed task.
// It returns and error if the `name` is already used.
func (c *Cron) AddSingleton(pattern string, job func(), name ...string) (*Entry, error) {
return c.AddEntry(pattern, job, -1, true, name...)
func (c *Cron) AddSingleton(ctx context.Context, pattern string, job JobFunc, name ...string) (*Entry, error) {
return c.AddEntry(ctx, pattern, job, -1, true, name...)
}
// AddTimes adds a timed task which can be run specified times.
// A unique `name` can be bound with the timed task.
// It returns and error if the `name` is already used.
func (c *Cron) AddTimes(pattern string, times int, job func(), name ...string) (*Entry, error) {
return c.AddEntry(pattern, job, times, false, name...)
func (c *Cron) AddTimes(ctx context.Context, pattern string, times int, job JobFunc, name ...string) (*Entry, error) {
return c.AddEntry(ctx, pattern, job, times, false, name...)
}
// AddOnce adds a timed task which can be run only once.
// A unique `name` can be bound with the timed task.
// It returns and error if the `name` is already used.
func (c *Cron) AddOnce(pattern string, job func(), name ...string) (*Entry, error) {
return c.AddEntry(pattern, job, 1, false, name...)
func (c *Cron) AddOnce(ctx context.Context, pattern string, job JobFunc, name ...string) (*Entry, error) {
return c.AddEntry(ctx, pattern, job, 1, false, name...)
}
// DelayAddEntry adds a timed task after `delay` time.
func (c *Cron) DelayAddEntry(delay time.Duration, pattern string, job func(), times int, singleton bool, name ...string) {
gtimer.AddOnce(delay, func() {
if _, err := c.AddEntry(pattern, job, times, singleton, name...); err != nil {
func (c *Cron) DelayAddEntry(ctx context.Context, delay time.Duration, pattern string, job JobFunc, times int, isSingleton bool, name ...string) {
gtimer.AddOnce(ctx, delay, func(ctx context.Context) {
if _, err := c.AddEntry(ctx, pattern, job, times, isSingleton, name...); err != nil {
panic(err)
}
})
}
// DelayAdd adds a timed task after `delay` time.
func (c *Cron) DelayAdd(delay time.Duration, pattern string, job func(), name ...string) {
gtimer.AddOnce(delay, func() {
if _, err := c.Add(pattern, job, name...); err != nil {
func (c *Cron) DelayAdd(ctx context.Context, delay time.Duration, pattern string, job JobFunc, name ...string) {
gtimer.AddOnce(ctx, delay, func(ctx context.Context) {
if _, err := c.Add(ctx, pattern, job, name...); err != nil {
panic(err)
}
})
}
// DelayAddSingleton adds a singleton timed task after `delay` time.
func (c *Cron) DelayAddSingleton(delay time.Duration, pattern string, job func(), name ...string) {
gtimer.AddOnce(delay, func() {
if _, err := c.AddSingleton(pattern, job, name...); err != nil {
func (c *Cron) DelayAddSingleton(ctx context.Context, delay time.Duration, pattern string, job JobFunc, name ...string) {
gtimer.AddOnce(ctx, delay, func(ctx context.Context) {
if _, err := c.AddSingleton(ctx, pattern, job, name...); err != nil {
panic(err)
}
})
@ -122,9 +124,9 @@ func (c *Cron) DelayAddSingleton(delay time.Duration, pattern string, job func()
// DelayAddOnce adds a timed task after `delay` time.
// This timed task can be run only once.
func (c *Cron) DelayAddOnce(delay time.Duration, pattern string, job func(), name ...string) {
gtimer.AddOnce(delay, func() {
if _, err := c.AddOnce(pattern, job, name...); err != nil {
func (c *Cron) DelayAddOnce(ctx context.Context, delay time.Duration, pattern string, job JobFunc, name ...string) {
gtimer.AddOnce(ctx, delay, func(ctx context.Context) {
if _, err := c.AddOnce(ctx, pattern, job, name...); err != nil {
panic(err)
}
})
@ -132,9 +134,9 @@ func (c *Cron) DelayAddOnce(delay time.Duration, pattern string, job func(), nam
// DelayAddTimes adds a timed task after `delay` time.
// This timed task can be run specified times.
func (c *Cron) DelayAddTimes(delay time.Duration, pattern string, times int, job func(), name ...string) {
gtimer.AddOnce(delay, func() {
if _, err := c.AddTimes(pattern, times, job, name...); err != nil {
func (c *Cron) DelayAddTimes(ctx context.Context, delay time.Duration, pattern string, times int, job JobFunc, name ...string) {
gtimer.AddOnce(ctx, delay, func(ctx context.Context) {
if _, err := c.AddTimes(ctx, pattern, times, job, name...); err != nil {
panic(err)
}
})

View File

@ -19,6 +19,8 @@ import (
"github.com/gogf/gf/v2/util/gconv"
)
type JobFunc = gtimer.JobFunc
// Entry is timing task entry.
type Entry struct {
cron *Cron // Cron object belonged to.
@ -28,21 +30,22 @@ type Entry struct {
times *gtype.Int // Running times limit.
infinite *gtype.Bool // No times limit.
Name string // Entry name.
Job func() `json:"-"` // Callback function.
Job JobFunc `json:"-"` // Callback function.
Time time.Time // Registered time.
}
type addEntryInput struct {
Name string // Name names this entry for manual control.
Job func() // Job is the callback function for timed task execution.
Times int // Times specifies the running limit times for the entry.
Pattern string // Pattern is the crontab style string for scheduler.
Singleton bool // Singleton specifies whether timed task executing in singleton mode.
Infinite bool // Infinite specifies whether this entry is running with no times limit.
type doAddEntryInput struct {
Name string // Name names this entry for manual control.
Job JobFunc // Job is the callback function for timed task execution.
Ctx context.Context // The context for the job.
Times int // Times specifies the running limit times for the entry.
Pattern string // Pattern is the crontab style string for scheduler.
IsSingleton bool // Singleton specifies whether timed task executing in singleton mode.
Infinite bool // Infinite specifies whether this entry is running with no times limit.
}
// doAddEntry creates and returns a new Entry object.
func (c *Cron) doAddEntry(in addEntryInput) (*Entry, error) {
func (c *Cron) doAddEntry(in doAddEntryInput) (*Entry, error) {
if in.Name != "" {
if c.Search(in.Name) != nil {
return nil, gerror.NewCodef(gcode.CodeInvalidOperation, `cron job "%s" already exists`, in.Name)
@ -72,7 +75,14 @@ func (c *Cron) doAddEntry(in addEntryInput) (*Entry, error) {
// It cannot start running when added to timer.
// It should start running after the entry is added to the Cron entries map, to avoid the task
// from running during adding where the entries do not have the entry information, which might cause panic.
entry.timerEntry = gtimer.AddEntry(time.Second, entry.check, in.Singleton, -1, gtimer.StatusStopped)
entry.timerEntry = gtimer.AddEntry(
in.Ctx,
time.Second,
entry.check,
in.IsSingleton,
-1,
gtimer.StatusStopped,
)
c.entries.Set(entry.Name, entry)
entry.timerEntry.Start()
return entry, nil
@ -123,10 +133,7 @@ func (entry *Entry) Close() {
// check is the core timing task check logic.
// The running times limits feature is implemented by gcron.Entry and cannot be implemented by gtimer.Entry.
// gcron.Entry relies on gtimer to implement a scheduled task check for gcron.Entry per second.
func (entry *Entry) check() {
var (
ctx = context.TODO()
)
func (entry *Entry) check(ctx context.Context) {
if entry.schedule.meet(time.Now()) {
switch entry.cron.status.Val() {
case StatusStopped:
@ -162,7 +169,7 @@ func (entry *Entry) check() {
}
entry.logDebugf(ctx, "[gcron] %s %s start", entry.schedule.pattern, entry.jobName)
entry.Job()
entry.Job(entry.timerEntry.Ctx())
}
}
}

View File

@ -25,11 +25,11 @@ func TestCron_Add_Close(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
_, err1 := cron.Add("* * * * * *", func() {
_, err1 := cron.Add(ctx, "* * * * * *", func(ctx context.Context) {
g.Log().Println(ctx, "cron1")
array.Append(1)
})
_, err2 := cron.Add("* * * * * *", func() {
_, err2 := cron.Add(ctx, "* * * * * *", func(ctx context.Context) {
g.Log().Println(ctx, "cron2")
array.Append(1)
}, "test")
@ -51,9 +51,9 @@ func TestCron_Add_Close(t *testing.T) {
func TestCron_Basic(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
cron.Add("* * * * * *", func() {}, "add")
cron.Add(ctx, "* * * * * *", func(ctx context.Context) {}, "add")
//fmt.Println("start", time.Now())
cron.DelayAdd(time.Second, "* * * * * *", func() {}, "delay_add")
cron.DelayAdd(ctx, time.Second, "* * * * * *", func(ctx context.Context) {}, "delay_add")
t.Assert(cron.Size(), 1)
time.Sleep(1200 * time.Millisecond)
t.Assert(cron.Size(), 2)
@ -72,7 +72,7 @@ func TestCron_Remove(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
cron.Add("* * * * * *", func() {
cron.Add(ctx, "* * * * * *", func(ctx context.Context) {
array.Append(1)
}, "add")
t.Assert(array.Len(), 0)
@ -90,8 +90,8 @@ func TestCron_AddSingleton(t *testing.T) {
// un used, can be removed
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
cron.Add("* * * * * *", func() {}, "add")
cron.DelayAdd(time.Second, "* * * * * *", func() {}, "delay_add")
cron.Add(ctx, "* * * * * *", func(ctx context.Context) {}, "add")
cron.DelayAdd(ctx, time.Second, "* * * * * *", func(ctx context.Context) {}, "delay_add")
t.Assert(cron.Size(), 1)
time.Sleep(1200 * time.Millisecond)
t.Assert(cron.Size(), 2)
@ -108,7 +108,7 @@ func TestCron_AddSingleton(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
cron.AddSingleton("* * * * * *", func() {
cron.AddSingleton(ctx, "* * * * * *", func(ctx context.Context) {
array.Append(1)
time.Sleep(50 * time.Second)
})
@ -123,10 +123,10 @@ func TestCron_AddOnce1(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
cron.AddOnce("* * * * * *", func() {
cron.AddOnce(ctx, "* * * * * *", func(ctx context.Context) {
array.Append(1)
})
cron.AddOnce("* * * * * *", func() {
cron.AddOnce(ctx, "* * * * * *", func(ctx context.Context) {
array.Append(1)
})
t.Assert(cron.Size(), 2)
@ -140,7 +140,7 @@ func TestCron_AddOnce2(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
cron.AddOnce("@every 2s", func() {
cron.AddOnce(ctx, "@every 2s", func(ctx context.Context) {
array.Append(1)
})
t.Assert(cron.Size(), 1)
@ -154,7 +154,7 @@ func TestCron_AddTimes(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
cron.AddTimes("* * * * * *", 2, func() {
cron.AddTimes(ctx, "* * * * * *", 2, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(3500 * time.Millisecond)
@ -167,7 +167,7 @@ func TestCron_DelayAdd(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
cron.DelayAdd(500*time.Millisecond, "* * * * * *", func() {
cron.DelayAdd(ctx, 500*time.Millisecond, "* * * * * *", func(ctx context.Context) {
array.Append(1)
})
t.Assert(cron.Size(), 0)
@ -184,7 +184,7 @@ func TestCron_DelayAddSingleton(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
cron.DelayAddSingleton(500*time.Millisecond, "* * * * * *", func() {
cron.DelayAddSingleton(ctx, 500*time.Millisecond, "* * * * * *", func(ctx context.Context) {
array.Append(1)
time.Sleep(10 * time.Second)
})
@ -199,7 +199,7 @@ func TestCron_DelayAddOnce(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
cron.DelayAddOnce(500*time.Millisecond, "* * * * * *", func() {
cron.DelayAddOnce(ctx, 500*time.Millisecond, "* * * * * *", func(ctx context.Context) {
array.Append(1)
})
t.Assert(cron.Size(), 0)
@ -216,7 +216,7 @@ func TestCron_DelayAddTimes(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
cron := gcron.New()
array := garray.New(true)
cron.DelayAddTimes(500*time.Millisecond, "* * * * * *", 2, func() {
cron.DelayAddTimes(ctx, 500*time.Millisecond, "* * * * * *", 2, func(ctx context.Context) {
array.Append(1)
})
t.Assert(cron.Size(), 0)

View File

@ -7,6 +7,7 @@
package gcron_test
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"testing"
"time"
@ -22,7 +23,7 @@ func TestCron_Entry_Operations(t *testing.T) {
cron = gcron.New()
array = garray.New(true)
)
cron.DelayAddTimes(500*time.Millisecond, "* * * * * *", 2, func() {
cron.DelayAddTimes(ctx, 500*time.Millisecond, "* * * * * *", 2, func(ctx context.Context) {
g.Log().Println(ctx, "add times")
array.Append(1)
})
@ -40,7 +41,7 @@ func TestCron_Entry_Operations(t *testing.T) {
cron = gcron.New()
array = garray.New(true)
)
entry, err1 := cron.Add("* * * * * *", func() {
entry, err1 := cron.Add(ctx, "* * * * * *", func(ctx context.Context) {
g.Log().Println(ctx, "add")
array.Append(1)
})

View File

@ -7,6 +7,7 @@
package gcron_test
import (
"context"
"testing"
"github.com/gogf/gf/v2/os/gcron"
@ -14,7 +15,7 @@ import (
func Benchmark_Add(b *testing.B) {
for i := 0; i < b.N; i++ {
gcron.Add("1 1 1 1 1 1", func() {
gcron.Add(ctx, "1 1 1 1 1 1", func(ctx context.Context) {
})
}

View File

@ -15,7 +15,7 @@ import (
)
func Example_cronAddSingleton() {
gcron.AddSingleton("* * * * * *", func() {
gcron.AddSingleton(ctx, "* * * * * *", func(ctx context.Context) {
glog.Println(context.TODO(), "doing")
time.Sleep(2 * time.Second)
})

View File

@ -106,7 +106,7 @@ func (l *Logger) print(ctx context.Context, level int, values ...interface{}) {
// It just initializes once for each logger.
if p.config.RotateSize > 0 || p.config.RotateExpire > 0 {
if !p.init.Val() && p.init.Cas(false, true) {
gtimer.AddOnce(p.config.RotateCheckInterval, p.rotateChecksTimely)
gtimer.AddOnce(context.Background(), p.config.RotateCheckInterval, p.rotateChecksTimely)
intlog.Printf(ctx, "logger rotation initialized: every %s", p.config.RotateCheckInterval.String())
}
}

View File

@ -106,12 +106,9 @@ func (l *Logger) doRotateFile(ctx context.Context, filePath string) error {
}
// rotateChecksTimely timely checks the backups expiration and the compression.
func (l *Logger) rotateChecksTimely() {
defer gtimer.AddOnce(l.config.RotateCheckInterval, l.rotateChecksTimely)
func (l *Logger) rotateChecksTimely(ctx context.Context) {
defer gtimer.AddOnce(ctx, l.config.RotateCheckInterval, l.rotateChecksTimely)
var (
ctx = context.TODO()
)
// Checks whether file rotation not enabled.
if l.config.RotateSize <= 0 && l.config.RotateExpire == 0 {
intlog.Printf(

View File

@ -67,12 +67,12 @@ func NewStorageFile(path ...string) *StorageFile {
updatingIdSet: gset.NewStrSet(true),
}
gtimer.AddSingleton(DefaultStorageFileLoopInterval, s.updateSessionTimely)
gtimer.AddSingleton(context.Background(), DefaultStorageFileLoopInterval, s.updateSessionTimely)
return s
}
// updateSessionTimely batch updates the TTL for sessions timely.
func (s *StorageFile) updateSessionTimely() {
func (s *StorageFile) updateSessionTimely(ctx context.Context) {
var (
id string
err error

View File

@ -44,7 +44,7 @@ func NewStorageRedis(redis *gredis.Redis, prefix ...string) *StorageRedis {
s.prefix = prefix[0]
}
// Batch updates the TTL for session ids timely.
gtimer.AddSingleton(DefaultStorageRedisLoopInterval, func() {
gtimer.AddSingleton(context.Background(), DefaultStorageRedisLoopInterval, func(ctx context.Context) {
intlog.Print(context.TODO(), "StorageRedis.timer start")
var (
id string

View File

@ -19,6 +19,7 @@
package gtimer
import (
"context"
"github.com/gogf/gf/v2/container/gtype"
"sync"
"time"
@ -64,19 +65,19 @@ func DefaultOptions() TimerOptions {
// SetTimeout runs the job once after duration of `delay`.
// It is like the one in javascript.
func SetTimeout(delay time.Duration, job JobFunc) {
AddOnce(delay, job)
func SetTimeout(ctx context.Context, delay time.Duration, job JobFunc) {
AddOnce(ctx, delay, job)
}
// SetInterval runs the job every duration of `delay`.
// It is like the one in javascript.
func SetInterval(interval time.Duration, job JobFunc) {
Add(interval, job)
func SetInterval(ctx context.Context, interval time.Duration, job JobFunc) {
Add(ctx, interval, job)
}
// Add adds a timing job to the default timer, which runs in interval of `interval`.
func Add(interval time.Duration, job JobFunc) *Entry {
return defaultTimer.Add(interval, job)
func Add(ctx context.Context, interval time.Duration, job JobFunc) *Entry {
return defaultTimer.Add(ctx, interval, job)
}
// AddEntry adds a timing job to the default timer with detailed parameters.
@ -90,53 +91,53 @@ func Add(interval time.Duration, job JobFunc) *Entry {
// exits if its run times exceeds the `times`.
//
// The parameter `status` specifies the job status when it's firstly added to the timer.
func AddEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
return defaultTimer.AddEntry(interval, job, singleton, times, status)
func AddEntry(ctx context.Context, interval time.Duration, job JobFunc, isSingleton bool, times int, status int) *Entry {
return defaultTimer.AddEntry(ctx, interval, job, isSingleton, times, status)
}
// AddSingleton is a convenience function for add singleton mode job.
func AddSingleton(interval time.Duration, job JobFunc) *Entry {
return defaultTimer.AddSingleton(interval, job)
func AddSingleton(ctx context.Context, interval time.Duration, job JobFunc) *Entry {
return defaultTimer.AddSingleton(ctx, interval, job)
}
// AddOnce is a convenience function for adding a job which only runs once and then exits.
func AddOnce(interval time.Duration, job JobFunc) *Entry {
return defaultTimer.AddOnce(interval, job)
func AddOnce(ctx context.Context, interval time.Duration, job JobFunc) *Entry {
return defaultTimer.AddOnce(ctx, interval, job)
}
// AddTimes is a convenience function for adding a job which is limited running times.
func AddTimes(interval time.Duration, times int, job JobFunc) *Entry {
return defaultTimer.AddTimes(interval, times, job)
func AddTimes(ctx context.Context, interval time.Duration, times int, job JobFunc) *Entry {
return defaultTimer.AddTimes(ctx, interval, times, job)
}
// DelayAdd adds a timing job after delay of `interval` duration.
// Also see Add.
func DelayAdd(delay time.Duration, interval time.Duration, job JobFunc) {
defaultTimer.DelayAdd(delay, interval, job)
func DelayAdd(ctx context.Context, delay time.Duration, interval time.Duration, job JobFunc) {
defaultTimer.DelayAdd(ctx, delay, interval, job)
}
// DelayAddEntry adds a timing job after delay of `interval` duration.
// Also see AddEntry.
func DelayAddEntry(delay time.Duration, interval time.Duration, job JobFunc, singleton bool, times int, status int) {
defaultTimer.DelayAddEntry(delay, interval, job, singleton, times, status)
func DelayAddEntry(ctx context.Context, delay time.Duration, interval time.Duration, job JobFunc, isSingleton bool, times int, status int) {
defaultTimer.DelayAddEntry(ctx, delay, interval, job, isSingleton, times, status)
}
// DelayAddSingleton adds a timing job after delay of `interval` duration.
// Also see AddSingleton.
func DelayAddSingleton(delay time.Duration, interval time.Duration, job JobFunc) {
defaultTimer.DelayAddSingleton(delay, interval, job)
func DelayAddSingleton(ctx context.Context, delay time.Duration, interval time.Duration, job JobFunc) {
defaultTimer.DelayAddSingleton(ctx, delay, interval, job)
}
// DelayAddOnce adds a timing job after delay of `interval` duration.
// Also see AddOnce.
func DelayAddOnce(delay time.Duration, interval time.Duration, job JobFunc) {
defaultTimer.DelayAddOnce(delay, interval, job)
func DelayAddOnce(ctx context.Context, delay time.Duration, interval time.Duration, job JobFunc) {
defaultTimer.DelayAddOnce(ctx, delay, interval, job)
}
// DelayAddTimes adds a timing job after delay of `interval` duration.
// Also see AddTimes.
func DelayAddTimes(delay time.Duration, interval time.Duration, times int, job JobFunc) {
defaultTimer.DelayAddTimes(delay, interval, times, job)
func DelayAddTimes(ctx context.Context, delay time.Duration, interval time.Duration, times int, job JobFunc) {
defaultTimer.DelayAddTimes(ctx, delay, interval, times, job)
}
// Exit is used in timing job internally, which exits and marks it closed from timer.

View File

@ -7,23 +7,25 @@
package gtimer
import (
"context"
"github.com/gogf/gf/v2/container/gtype"
)
// Entry is the timing job.
type Entry struct {
job JobFunc // The job function.
timer *Timer // Belonged timer.
ticks int64 // The job runs every tick.
times *gtype.Int // Limit running times.
status *gtype.Int // Job status.
singleton *gtype.Bool // Singleton mode.
nextTicks *gtype.Int64 // Next run ticks of the job.
infinite *gtype.Bool // No times limit.
job JobFunc // The job function.
ctx context.Context // The context for the job.
timer *Timer // Belonged timer.
ticks int64 // The job runs every tick.
times *gtype.Int // Limit running times.
status *gtype.Int // Job status.
isSingleton *gtype.Bool // Singleton mode.
nextTicks *gtype.Int64 // Next run ticks of the job.
infinite *gtype.Bool // No times limit.
}
// JobFunc is the job function.
type JobFunc = func()
type JobFunc = func(ctx context.Context)
// Status returns the status of the job.
func (entry *Entry) Status() int {
@ -54,7 +56,7 @@ func (entry *Entry) Run() {
entry.SetStatus(StatusReady)
}
}()
entry.job()
entry.job(entry.ctx)
}()
}
@ -113,12 +115,12 @@ func (entry *Entry) Reset() {
// IsSingleton checks and returns whether the job in singleton mode.
func (entry *Entry) IsSingleton() bool {
return entry.singleton.Val()
return entry.isSingleton.Val()
}
// SetSingleton sets the job singleton mode.
func (entry *Entry) SetSingleton(enabled bool) {
entry.singleton.Set(enabled)
entry.isSingleton.Set(enabled)
}
// Job returns the job function of this job.
@ -126,6 +128,11 @@ func (entry *Entry) Job() JobFunc {
return entry.job
}
// Ctx returns the initialized context of this job.
func (entry *Entry) Ctx() context.Context {
return entry.ctx
}
// SetTimes sets the limit running times for the job.
func (entry *Entry) SetTimes(times int) {
entry.times.Set(times)

View File

@ -7,6 +7,7 @@
package gtimer
import (
"context"
"github.com/gogf/gf/v2/container/gtype"
"time"
)
@ -27,8 +28,15 @@ func New(options ...TimerOptions) *Timer {
}
// Add adds a timing job to the timer, which runs in interval of `interval`.
func (t *Timer) Add(interval time.Duration, job JobFunc) *Entry {
return t.createEntry(interval, job, false, -1, StatusReady)
func (t *Timer) Add(ctx context.Context, interval time.Duration, job JobFunc) *Entry {
return t.createEntry(createEntryInput{
Ctx: ctx,
Interval: interval,
Job: job,
IsSingleton: false,
Times: -1,
Status: StatusReady,
})
}
// AddEntry adds a timing job to the timer with detailed parameters.
@ -36,68 +44,96 @@ func (t *Timer) Add(interval time.Duration, job JobFunc) *Entry {
// The parameter `interval` specifies the running interval of the job.
//
// The parameter `singleton` specifies whether the job running in singleton mode.
// There's only one of the same job is allowed running when its a singleton mode job.
// There's only one of the same job is allowed running when it's a singleton mode job.
//
// The parameter `times` specifies limit for the job running times, which means the job
// exits if its run times exceeds the `times`.
//
// The parameter `status` specifies the job status when it's firstly added to the timer.
func (t *Timer) AddEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
return t.createEntry(interval, job, singleton, times, status)
func (t *Timer) AddEntry(ctx context.Context, interval time.Duration, job JobFunc, isSingleton bool, times int, status int) *Entry {
return t.createEntry(createEntryInput{
Ctx: ctx,
Interval: interval,
Job: job,
IsSingleton: isSingleton,
Times: times,
Status: status,
})
}
// AddSingleton is a convenience function for add singleton mode job.
func (t *Timer) AddSingleton(interval time.Duration, job JobFunc) *Entry {
return t.createEntry(interval, job, true, -1, StatusReady)
func (t *Timer) AddSingleton(ctx context.Context, interval time.Duration, job JobFunc) *Entry {
return t.createEntry(createEntryInput{
Ctx: ctx,
Interval: interval,
Job: job,
IsSingleton: true,
Times: -1,
Status: StatusReady,
})
}
// AddOnce is a convenience function for adding a job which only runs once and then exits.
func (t *Timer) AddOnce(interval time.Duration, job JobFunc) *Entry {
return t.createEntry(interval, job, true, 1, StatusReady)
func (t *Timer) AddOnce(ctx context.Context, interval time.Duration, job JobFunc) *Entry {
return t.createEntry(createEntryInput{
Ctx: ctx,
Interval: interval,
Job: job,
IsSingleton: true,
Times: 1,
Status: StatusReady,
})
}
// AddTimes is a convenience function for adding a job which is limited running times.
func (t *Timer) AddTimes(interval time.Duration, times int, job JobFunc) *Entry {
return t.createEntry(interval, job, true, times, StatusReady)
func (t *Timer) AddTimes(ctx context.Context, interval time.Duration, times int, job JobFunc) *Entry {
return t.createEntry(createEntryInput{
Ctx: ctx,
Interval: interval,
Job: job,
IsSingleton: true,
Times: times,
Status: StatusReady,
})
}
// DelayAdd adds a timing job after delay of `interval` duration.
// Also see Add.
func (t *Timer) DelayAdd(delay time.Duration, interval time.Duration, job JobFunc) {
t.AddOnce(delay, func() {
t.Add(interval, job)
func (t *Timer) DelayAdd(ctx context.Context, delay time.Duration, interval time.Duration, job JobFunc) {
t.AddOnce(ctx, delay, func(ctx context.Context) {
t.Add(ctx, interval, job)
})
}
// DelayAddEntry adds a timing job after delay of `interval` duration.
// Also see AddEntry.
func (t *Timer) DelayAddEntry(delay time.Duration, interval time.Duration, job JobFunc, singleton bool, times int, status int) {
t.AddOnce(delay, func() {
t.AddEntry(interval, job, singleton, times, status)
func (t *Timer) DelayAddEntry(ctx context.Context, delay time.Duration, interval time.Duration, job JobFunc, isSingleton bool, times int, status int) {
t.AddOnce(ctx, delay, func(ctx context.Context) {
t.AddEntry(ctx, interval, job, isSingleton, times, status)
})
}
// DelayAddSingleton adds a timing job after delay of `interval` duration.
// Also see AddSingleton.
func (t *Timer) DelayAddSingleton(delay time.Duration, interval time.Duration, job JobFunc) {
t.AddOnce(delay, func() {
t.AddSingleton(interval, job)
func (t *Timer) DelayAddSingleton(ctx context.Context, delay time.Duration, interval time.Duration, job JobFunc) {
t.AddOnce(ctx, delay, func(ctx context.Context) {
t.AddSingleton(ctx, interval, job)
})
}
// DelayAddOnce adds a timing job after delay of `interval` duration.
// Also see AddOnce.
func (t *Timer) DelayAddOnce(delay time.Duration, interval time.Duration, job JobFunc) {
t.AddOnce(delay, func() {
t.AddOnce(interval, job)
func (t *Timer) DelayAddOnce(ctx context.Context, delay time.Duration, interval time.Duration, job JobFunc) {
t.AddOnce(ctx, delay, func(ctx context.Context) {
t.AddOnce(ctx, interval, job)
})
}
// DelayAddTimes adds a timing job after delay of `interval` duration.
// Also see AddTimes.
func (t *Timer) DelayAddTimes(delay time.Duration, interval time.Duration, times int, job JobFunc) {
t.AddOnce(delay, func() {
t.AddTimes(interval, times, job)
func (t *Timer) DelayAddTimes(ctx context.Context, delay time.Duration, interval time.Duration, times int, job JobFunc) {
t.AddOnce(ctx, delay, func(ctx context.Context) {
t.AddTimes(ctx, interval, times, job)
})
}
@ -116,16 +152,25 @@ func (t *Timer) Close() {
t.status.Set(StatusClosed)
}
type createEntryInput struct {
Ctx context.Context
Interval time.Duration
Job JobFunc
IsSingleton bool
Times int
Status int
}
// createEntry creates and adds a timing job to the timer.
func (t *Timer) createEntry(interval time.Duration, job JobFunc, singleton bool, times int, status int) *Entry {
func (t *Timer) createEntry(in createEntryInput) *Entry {
var (
infinite = false
)
if times <= 0 {
if in.Times <= 0 {
infinite = true
}
var (
intervalTicksOfJob = int64(interval / t.options.Interval)
intervalTicksOfJob = int64(in.Interval / t.options.Interval)
)
if intervalTicksOfJob == 0 {
// If the given interval is lesser than the one of the wheel,
@ -135,14 +180,15 @@ func (t *Timer) createEntry(interval time.Duration, job JobFunc, singleton bool,
var (
nextTicks = t.ticks.Val() + intervalTicksOfJob
entry = &Entry{
job: job,
timer: t,
ticks: intervalTicksOfJob,
times: gtype.NewInt(times),
status: gtype.NewInt(status),
singleton: gtype.NewBool(singleton),
nextTicks: gtype.NewInt64(nextTicks),
infinite: gtype.NewBool(infinite),
job: in.Job,
ctx: in.Ctx,
timer: t,
ticks: intervalTicksOfJob,
times: gtype.NewInt(in.Times),
status: gtype.NewInt(in.Status),
isSingleton: gtype.NewBool(in.IsSingleton),
nextTicks: gtype.NewInt64(nextTicks),
infinite: gtype.NewBool(infinite),
}
)
t.queue.Push(entry, nextTicks)

View File

@ -7,17 +7,19 @@
package gtimer
import (
"context"
"testing"
"time"
)
var (
ctx = context.TODO()
timer = New()
)
func Benchmark_Add(b *testing.B) {
for i := 0; i < b.N; i++ {
timer.Add(time.Hour, func() {
timer.Add(ctx, time.Hour, func(ctx context.Context) {
})
}

View File

@ -7,6 +7,7 @@
package gtimer_test
import (
"context"
"fmt"
"time"
@ -14,9 +15,12 @@ import (
)
func Example_add() {
now := time.Now()
interval := 1400 * time.Millisecond
gtimer.Add(interval, func() {
var (
ctx = context.Background()
now = time.Now()
interval = 1400 * time.Millisecond
)
gtimer.Add(ctx, interval, func(ctx context.Context) {
fmt.Println(time.Now(), time.Duration(time.Now().UnixNano()-now.UnixNano()))
now = time.Now()
})

View File

@ -9,6 +9,7 @@
package gtimer_test
import (
"context"
"testing"
"time"
@ -17,10 +18,14 @@ import (
"github.com/gogf/gf/v2/test/gtest"
)
var (
ctx = context.TODO()
)
func TestSetTimeout(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.SetTimeout(200*time.Millisecond, func() {
gtimer.SetTimeout(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(1000 * time.Millisecond)
@ -31,7 +36,7 @@ func TestSetTimeout(t *testing.T) {
func TestSetInterval(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.SetInterval(300*time.Millisecond, func() {
gtimer.SetInterval(ctx, 300*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(1000 * time.Millisecond)
@ -42,7 +47,7 @@ func TestSetInterval(t *testing.T) {
func TestAddEntry(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.AddEntry(200*time.Millisecond, func() {
gtimer.AddEntry(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
}, false, 2, gtimer.StatusReady)
time.Sleep(1100 * time.Millisecond)
@ -53,7 +58,7 @@ func TestAddEntry(t *testing.T) {
func TestAddSingleton(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.AddSingleton(200*time.Millisecond, func() {
gtimer.AddSingleton(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
time.Sleep(10000 * time.Millisecond)
})
@ -65,7 +70,7 @@ func TestAddSingleton(t *testing.T) {
func TestAddTimes(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.AddTimes(200*time.Millisecond, 2, func() {
gtimer.AddTimes(ctx, 200*time.Millisecond, 2, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(1000 * time.Millisecond)
@ -76,7 +81,7 @@ func TestAddTimes(t *testing.T) {
func TestDelayAdd(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.DelayAdd(500*time.Millisecond, 500*time.Millisecond, func() {
gtimer.DelayAdd(ctx, 500*time.Millisecond, 500*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(600 * time.Millisecond)
@ -89,7 +94,7 @@ func TestDelayAdd(t *testing.T) {
func TestDelayAddEntry(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.DelayAddEntry(200*time.Millisecond, 200*time.Millisecond, func() {
gtimer.DelayAddEntry(ctx, 200*time.Millisecond, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
}, false, 2, gtimer.StatusReady)
time.Sleep(300 * time.Millisecond)
@ -102,7 +107,7 @@ func TestDelayAddEntry(t *testing.T) {
func TestDelayAddSingleton(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.DelayAddSingleton(500*time.Millisecond, 500*time.Millisecond, func() {
gtimer.DelayAddSingleton(ctx, 500*time.Millisecond, 500*time.Millisecond, func(ctx context.Context) {
array.Append(1)
time.Sleep(10000 * time.Millisecond)
})
@ -116,7 +121,7 @@ func TestDelayAddSingleton(t *testing.T) {
func TestDelayAddOnce(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.DelayAddOnce(200*time.Millisecond, 200*time.Millisecond, func() {
gtimer.DelayAddOnce(ctx, 200*time.Millisecond, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(300 * time.Millisecond)
@ -129,7 +134,7 @@ func TestDelayAddOnce(t *testing.T) {
func TestDelayAddTimes(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
array := garray.New(true)
gtimer.DelayAddTimes(500*time.Millisecond, 500*time.Millisecond, 2, func() {
gtimer.DelayAddTimes(ctx, 500*time.Millisecond, 500*time.Millisecond, 2, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(300 * time.Millisecond)

View File

@ -9,6 +9,7 @@
package gtimer_test
import (
"context"
"testing"
"time"
@ -21,7 +22,7 @@ func TestJob_Start_Stop_Close(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
job := timer.Add(200*time.Millisecond, func() {
job := timer.Add(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(250 * time.Millisecond)
@ -44,7 +45,7 @@ func TestJob_Singleton(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
job := timer.Add(200*time.Millisecond, func() {
job := timer.Add(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
time.Sleep(10 * time.Second)
})
@ -63,7 +64,7 @@ func TestJob_SetTimes(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
job := timer.Add(200*time.Millisecond, func() {
job := timer.Add(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
job.SetTimes(2)
@ -77,10 +78,10 @@ func TestJob_Run(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
job := timer.Add(1000*time.Millisecond, func() {
job := timer.Add(ctx, 1000*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
job.Job()()
job.Job()(ctx)
t.Assert(array.Len(), 1)
})
}

View File

@ -7,6 +7,7 @@
package gtimer
import (
"context"
"github.com/gogf/gf/v2/container/garray"
"github.com/gogf/gf/v2/test/gtest"
"testing"
@ -19,7 +20,7 @@ func TestTimer_Proceed(t *testing.T) {
timer := New(TimerOptions{
Interval: time.Hour,
})
timer.Add(10000*time.Hour, func() {
timer.Add(ctx, 10000*time.Hour, func(ctx context.Context) {
array.Append(1)
})
timer.proceed(10001)
@ -34,7 +35,7 @@ func TestTimer_Proceed(t *testing.T) {
timer := New(TimerOptions{
Interval: time.Millisecond * 100,
})
timer.Add(10000*time.Hour, func() {
timer.Add(ctx, 10000*time.Hour, func(ctx context.Context) {
array.Append(1)
})
ticks := int64((10000 * time.Hour) / (time.Millisecond * 100))

View File

@ -9,6 +9,7 @@
package gtimer_test
import (
"context"
"testing"
"time"
@ -26,15 +27,15 @@ func TestTimer_Add_Close(t *testing.T) {
timer := New()
array := garray.New(true)
//fmt.Println("start", time.Now())
timer.Add(200*time.Millisecond, func() {
timer.Add(ctx, 200*time.Millisecond, func(ctx context.Context) {
//fmt.Println("job1", time.Now())
array.Append(1)
})
timer.Add(200*time.Millisecond, func() {
timer.Add(ctx, 200*time.Millisecond, func(ctx context.Context) {
//fmt.Println("job2", time.Now())
array.Append(1)
})
timer.Add(400*time.Millisecond, func() {
timer.Add(ctx, 400*time.Millisecond, func(ctx context.Context) {
//fmt.Println("job3", time.Now())
array.Append(1)
})
@ -54,7 +55,7 @@ func TestTimer_Start_Stop_Close(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.Add(1000*time.Millisecond, func() {
timer.Add(ctx, 1000*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
t.Assert(array.Len(), 0)
@ -76,7 +77,7 @@ func TestJob_Reset(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
job := timer.AddSingleton(500*time.Millisecond, func() {
job := timer.AddSingleton(ctx, 500*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(300 * time.Millisecond)
@ -94,7 +95,7 @@ func TestTimer_AddSingleton(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.AddSingleton(200*time.Millisecond, func() {
timer.AddSingleton(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
time.Sleep(10 * time.Second)
})
@ -110,10 +111,10 @@ func TestTimer_AddOnce(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.AddOnce(200*time.Millisecond, func() {
timer.AddOnce(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
timer.AddOnce(200*time.Millisecond, func() {
timer.AddOnce(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(250 * time.Millisecond)
@ -132,7 +133,7 @@ func TestTimer_AddTimes(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.AddTimes(200*time.Millisecond, 2, func() {
timer.AddTimes(ctx, 200*time.Millisecond, 2, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(1000 * time.Millisecond)
@ -144,7 +145,7 @@ func TestTimer_DelayAdd(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.DelayAdd(200*time.Millisecond, 200*time.Millisecond, func() {
timer.DelayAdd(ctx, 200*time.Millisecond, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(250 * time.Millisecond)
@ -158,7 +159,7 @@ func TestTimer_DelayAddJob(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.DelayAddEntry(200*time.Millisecond, 200*time.Millisecond, func() {
timer.DelayAddEntry(ctx, 200*time.Millisecond, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
}, false, 100, gtimer.StatusReady)
time.Sleep(250 * time.Millisecond)
@ -172,7 +173,7 @@ func TestTimer_DelayAddSingleton(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.DelayAddSingleton(200*time.Millisecond, 200*time.Millisecond, func() {
timer.DelayAddSingleton(ctx, 200*time.Millisecond, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
time.Sleep(10 * time.Second)
})
@ -188,7 +189,7 @@ func TestTimer_DelayAddOnce(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.DelayAddOnce(200*time.Millisecond, 200*time.Millisecond, func() {
timer.DelayAddOnce(ctx, 200*time.Millisecond, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(250 * time.Millisecond)
@ -206,7 +207,7 @@ func TestTimer_DelayAddTimes(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.DelayAddTimes(200*time.Millisecond, 500*time.Millisecond, 2, func() {
timer.DelayAddTimes(ctx, 200*time.Millisecond, 500*time.Millisecond, 2, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(200 * time.Millisecond)
@ -229,7 +230,7 @@ func TestTimer_AddLessThanInterval(t *testing.T) {
Interval: 100 * time.Millisecond,
})
array := garray.New(true)
timer.Add(20*time.Millisecond, func() {
timer.Add(ctx, 20*time.Millisecond, func(ctx context.Context) {
array.Append(1)
})
time.Sleep(50 * time.Millisecond)
@ -248,7 +249,7 @@ func TestTimer_AddLeveledJob1(t *testing.T) {
timer := New()
array := garray.New(true)
//glog.Println("start")
timer.DelayAdd(1000*time.Millisecond, 1000*time.Millisecond, func() {
timer.DelayAdd(ctx, 1000*time.Millisecond, 1000*time.Millisecond, func(ctx context.Context) {
//glog.Println("add")
array.Append(1)
})
@ -264,7 +265,7 @@ func TestTimer_Exit(t *testing.T) {
gtest.C(t, func(t *gtest.T) {
timer := New()
array := garray.New(true)
timer.Add(200*time.Millisecond, func() {
timer.Add(ctx, 200*time.Millisecond, func(ctx context.Context) {
array.Append(1)
gtimer.Exit()
})