scheduler

package module
v0.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 28, 2025 License: MIT Imports: 8 Imported by: 2

README

Scheduler Provider

Scheduler Provider là giải pháp lên lịch và chạy các task định kỳ cho ứng dụng Go, được xây dựng dựa trên thư viện go-co-op/gocron.

Tính năng nổi bật

  • Configuration-driven: Hỗ trợ cấu hình qua file config với struct Config và RedisLockerOptions
  • Auto-start: Tự động khởi động scheduler khi ứng dụng boot (có thể tắt qua config)
  • Distributed Locking: Hỗ trợ distributed locking với Redis cho môi trường phân tán
  • Fluent API: API fluent cho trải nghiệm lập trình dễ dàng
  • Tích hợp DI: Tích hợp toàn bộ tính năng vào DI container của ứng dụng
  • Multiple Schedule Types: Hỗ trợ nhiều loại lịch trình (khoảng thời gian, thời điểm cụ thể, cron expressions)
  • Singleton Mode: Hỗ trợ chế độ singleton để tránh chạy song song cùng một task
  • Task Management: Hỗ trợ tag để nhóm và quản lý các task

Cài đặt

go get github.com/go-fork/providers/scheduler

Cấu hình

File cấu hình (config/app.yaml)
scheduler:
  # Tự động khởi động scheduler khi ứng dụng boot
  auto_start: true

  # Distributed locking với Redis (tùy chọn)
  distributed_lock:
    enabled: false
  
  # Cài đặt RedisLockerOptions cho distributed locking
  options:
    key_prefix: "scheduler_lock:"
    lock_duration: 30      # seconds
    max_retries: 3
    retry_delay: 100       # milliseconds
Các tùy chọn cấu hình
Field Type Mô tả Mặc định
auto_start bool Tự động khởi động scheduler trong Boot() true
distributed_lock.enabled bool Bật distributed locking với Redis false
options.key_prefix string Tiền tố key trong Redis "scheduler_lock:"
options.lock_duration int Thời gian lock (giây) 30
options.max_retries int Số lần thử lại 3
options.retry_delay int Thời gian chờ giữa các lần thử (ms) 100

Cách sử dụng

1. Đăng ký Service Provider
package main

import (
    "github.com/go-fork/di"
    "github.com/go-fork/providers/scheduler"
)

func main() {
    app := di.New()
    app.Register(scheduler.NewServiceProvider())
    
    // Khởi động ứng dụng
    app.Boot()
    
    // Giữ ứng dụng chạy để scheduler có thể hoạt động
    select {}
}
2. Lấy scheduler từ container và lên lịch cho task
// Lấy scheduler từ container
container := app.Container()
sched := container.Get("scheduler").(scheduler.Manager)

// Đăng ký task chạy mỗi 5 phút
sched.Every(5).Minutes().Do(func() {
    fmt.Println("Task runs every 5 minutes")
})

// Đăng ký task với cron expression
sched.Cron("0 0 * * *").Do(func() {
    fmt.Println("Task runs at midnight every day")
})

// Đăng ký task với tag để dễ quản lý
sched.Every(1).Hour().Tag("maintenance").Do(func() {
    fmt.Println("Maintenance task runs hourly")
})
3. Sử dụng Configuration-driven Scheduler

Scheduler provider hỗ trợ cấu hình tự động thông qua file config. Khi có cấu hình distributed locking, provider sẽ tự động tạo và thiết lập Redis locker:

# config/app.yaml
scheduler:
  auto_start: true
  distributed_lock:
    enabled: true
  options:
    key_prefix: "myapp_scheduler:"
    lock_duration: 60      # seconds
    max_retries: 5
    retry_delay: 200       # milliseconds

# Cần cả redis provider để kết nối Redis
redis:
  default:
    addr: "localhost:6379"
    password: ""
    db: 0
import (
    "github.com/go-fork/di"
    "github.com/go-fork/providers/config"
    "github.com/go-fork/providers/redis"
    "github.com/go-fork/providers/scheduler"
)

func main() {
    app := di.New()
    
    // Đăng ký các providers theo thứ tự phụ thuộc
    app.Register(config.NewServiceProvider())
    app.Register(redis.NewServiceProvider())  // Required cho distributed locking
    app.Register(scheduler.NewServiceProvider())
    
    // Khởi động ứng dụng - scheduler sẽ tự động cấu hình distributed locking
    app.Boot()
    
    // Sử dụng scheduler đã được cấu hình sẵn
    container := app.Container()
    sched := container.Get("scheduler").(scheduler.Manager)
    
    // Tất cả jobs sẽ tự động sử dụng distributed locking nếu được bật
    sched.Every(5).Minutes().Do(func() {
        fmt.Println("This task uses distributed locking automatically")
    })
    
    select {}
}
4. Sử dụng Manual Redis Locker (Tùy chọn)

Nếu bạn muốn tự thiết lập Redis locker thay vì dùng config:

import (
    "github.com/redis/go-redis/v9"
    "github.com/go-fork/providers/scheduler"
)

// Khởi tạo Redis client
redisClient := redis.NewClient(&redis.Options{
    Addr:     "localhost:6379",
    Password: "",
    DB:       0,
})

// Tạo Redis Locker với tùy chọn tùy chỉnh
customLocker, err := scheduler.NewRedisLocker(redisClient, scheduler.RedisLockerOptions{
    KeyPrefix:    "myapp_scheduler:",
    LockDuration: 60,   // seconds (int value)
    MaxRetries:   5,
    RetryDelay:   200,  // milliseconds (int value)
})
if err != nil {
    log.Fatal(err)
}

// Thiết lập Redis Locker cho scheduler
sched := container.Get("scheduler").(scheduler.Manager)
sched.WithDistributedLocker(customLocker)

Các tùy chọn cấu hình của Redis Locker:

Tùy chọn Mô tả Giá trị mặc định
KeyPrefix Tiền tố được thêm vào trước mỗi khóa trong Redis scheduler_lock:
LockDuration Thời gian một khóa sẽ tồn tại trước khi tự động hết hạn (giây) 30
MaxRetries Số lần thử tối đa khi gặp lỗi khi tương tác với Redis 3
RetryDelay Thời gian chờ giữa các lần thử (milliseconds) 100
5. Quản lý các task
// Xóa task theo tag
sched.RemoveByTag("maintenance")

// Xóa tất cả task
sched.Clear()

// Tạm dừng scheduler
sched.Stop()

// Khởi động lại scheduler
sched.Start()
6. Tùy chỉnh Scheduler
// Đặt thời gian múi giờ cho scheduler
sched.Location(time.UTC)

// Đặt singleton mode cho scheduler 
// (không chạy nhiều instance của cùng một job)
sched.SingletonMode().Every(1).Minute().Do(func() {
    // Task sẽ không chạy song song nếu lần chạy trước chưa hoàn thành
    longRunningTask()
})

Tính năng tự động gia hạn khóa Redis

Khi sử dụng Redis Distributed Locker, scheduler triển khai cơ chế tự động gia hạn khóa để đảm bảo job không bị gián đoạn khi chạy thời gian dài:

  • Khóa Redis được tự động gia hạn sau khi đã chạy được 2/3 thời gian hết hạn
  • Việc gia hạn xảy ra trong một goroutine riêng biệt
  • Khi job hoàn thành, khóa sẽ được giải phóng
  • Nếu instance gặp sự cố, khóa sẽ tự động hết hạn sau LockDuration

Các ví dụ nâng cao

Chạy task với tham số
sched.Every(1).Day().Do(func(name string) {
    fmt.Printf("Hello %s\n", name)
}, "John")
Chạy task vào thời điểm cụ thể
sched.Every(1).Day().At("10:30").Do(func() {
    fmt.Println("Task runs at 10:30 AM daily")
})

// Hoặc sử dụng cron expression
sched.Cron("30 10 * * *").Do(func() {
    fmt.Println("Task runs at 10:30 AM daily")
})
Xử lý lỗi từ task
job, err := sched.Every(1).Minute().Do(func() error {
    // Công việc có thể trả về lỗi
    if somethingWrong {
        return errors.New("something went wrong")
    }
    return nil
})

if err != nil {
    log.Fatal(err)
}

// Đăng ký hàm xử lý khi task trả về lỗi
job.OnError(func(err error) {
    log.Printf("Job failed: %v", err)
})

Yêu cầu hệ thống

  • Go 1.18 trở lên
  • Redis (tùy chọn, chỉ khi sử dụng distributed locking)

Giấy phép

Mã nguồn này được phân phối dưới giấy phép MIT.

Documentation

Overview

Package scheduler cung cấp giải pháp lên lịch và chạy các task định kỳ cho ứng dụng Go, dựa trên thư viện gocron.

Tính năng nổi bật:

  • Configuration-driven: Hỗ trợ cấu hình qua file config với struct Config và RedisLockerOptions
  • Auto-start: Tự động khởi động scheduler khi ứng dụng boot (có thể tắt qua config)
  • Wrap toàn bộ tính năng của thư viện gocron - một thư viện lập lịch và chạy task hiệu quả
  • Hỗ trợ nhiều loại lịch trình: theo khoảng thời gian, theo thời điểm cụ thể, biểu thức cron
  • Hỗ trợ chế độ singleton để tránh chạy song song cùng một task
  • Hỗ trợ distributed locking với Redis cho môi trường phân tán (tự động cấu hình qua config)
  • Hỗ trợ tag để nhóm và quản lý các task
  • Tích hợp với DI container thông qua ServiceProvider
  • API fluent cho trải nghiệm lập trình dễ dàng

Kiến trúc và cách hoạt động:

  • Sử dụng mô hình embedding để triển khai interface Manager trực tiếp nhúng gocron.Scheduler
  • Cung cấp fluent interface để cấu hình task một cách dễ dàng và rõ ràng
  • ServiceProvider giúp tích hợp dễ dàng vào ứng dụng thông qua DI container
  • Hỗ trợ dual config system: RedisLockerOptions (int) cho file config và RedisLockerOptionsTime (time.Duration) cho internal use
  • Tự động khởi động scheduler khi ứng dụng boot (có thể tắt thông qua config auto_start: false)
  • Tự động thiết lập distributed locking khi được enable trong config và có redis provider
  • Hỗ trợ tự động gia hạn khóa cho distributed locking trong môi trường phân tán

Ví dụ sử dụng với configuration-driven approach:

// config/app.yaml
scheduler:
  auto_start: true
  distributed_lock:
    enabled: true
  options:
    key_prefix: "myapp_scheduler:"
    lock_duration: 60    # seconds
    max_retries: 5
    retry_delay: 200     # milliseconds

redis:
  default:
    addr: "localhost:6379"
    password: ""
    db: 0

// Đăng ký service providers
app := di.New()
app.Register(config.NewServiceProvider())
app.Register(redis.NewServiceProvider())  // Required cho distributed locking
app.Register(scheduler.NewServiceProvider())

// Boot ứng dụng - scheduler tự động cấu hình
app.Boot()

// Lấy scheduler từ container
container := app.Container()
sched := container.Get("scheduler").(scheduler.Manager)

// Đăng ký task chạy mỗi 5 phút với distributed locking tự động
sched.Every(5).Minutes().Do(func() {
	fmt.Println("Task runs every 5 minutes with distributed locking")
})

// Đăng ký task với cron expression
sched.Cron("0 0 * * *").Do(func() {
	fmt.Println("Task runs at midnight every day")
})

// Đăng ký task với tag để dễ quản lý
sched.Every(1).Hour().Tag("maintenance").Do(func() {
	fmt.Println("Maintenance task runs hourly")
})

Sử dụng Manual Redis Locker (tùy chọn thay vì config):

import (
	"github.com/redis/go-redis/v9"
)

// Khởi tạo Redis client
redisClient := redis.NewClient(&redis.Options{
	Addr:     "localhost:6379",
	Password: "",
	DB:       0,
})

// Tạo Redis Locker với tùy chọn mặc định
locker, err := scheduler.NewRedisLocker(redisClient)
if err != nil {
	log.Fatal(err)
}

// Hoặc với tùy chọn tùy chỉnh (sử dụng int values cho config)
customLocker, err := scheduler.NewRedisLocker(redisClient, scheduler.RedisLockerOptions{
	KeyPrefix:    "myapp_scheduler:",
	LockDuration: 60,   // seconds (int value)
	MaxRetries:   5,
	RetryDelay:   200,  // milliseconds (int value)
})
if err != nil {
	log.Fatal(err)
}

// Lấy scheduler từ container
sched := container.Get("scheduler").(scheduler.Manager)

// Thiết lập Redis Locker cho scheduler
sched.WithDistributedLocker(locker)

// Từ bây giờ, tất cả các jobs sẽ sử dụng distributed locking với Redis
// để đảm bảo chỉ chạy một lần trong môi trường phân tán

Gói này giúp đơn giản hóa việc lên lịch và chạy các task định kỳ trong ứng dụng Go, đồng thời tích hợp dễ dàng với kiến trúc ứng dụng thông qua DI container và hỗ trợ configuration-driven approach cho việc thiết lập distributed locking.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrRedisClientNil được trả về khi Redis client nil.
	ErrRedisClientNil = errors.New("scheduler: redis client is nil")

	// ErrFailedToConnectToRedis được trả về khi không thể kết nối đến Redis.
	ErrFailedToConnectToRedis = errors.New("scheduler: failed to connect to redis")

	// ErrFailedToAcquireLock được trả về khi không thể lấy lock sau số lần thử tối đa.
	ErrFailedToAcquireLock = errors.New("scheduler: failed to acquire lock after maximum retries")

	// ErrInvalidLockDuration được trả về khi LockDuration không hợp lệ.
	ErrInvalidLockDuration = errors.New("scheduler: invalid lock duration")

	// ErrInvalidMaxRetries được trả về khi MaxRetries không hợp lệ.
	ErrInvalidMaxRetries = errors.New("scheduler: invalid max retries")

	// ErrInvalidRetryDelay được trả về khi RetryDelay không hợp lệ.
	ErrInvalidRetryDelay = errors.New("scheduler: invalid retry delay")

	// ErrInvalidKeyPrefix được trả về khi KeyPrefix không hợp lệ.
	ErrInvalidKeyPrefix = errors.New("scheduler: invalid key prefix")
)

Error constants

Functions

func NewRedisLocker

func NewRedisLocker(client *redis.Client, opts ...RedisLockerOptions) (gocron.Locker, error)

NewRedisLocker tạo một Redis Locker mới để sử dụng với gocron. Nó có thể được chuyển vào phương thức WithDistributedLocker của scheduler.

Example:

redisClient := redis.NewClient(&redis.Options{
	Addr: "localhost:6379",
})
locker, err := scheduler.NewRedisLocker(redisClient)
if err != nil {
	log.Fatal(err)
}
sched.WithDistributedLocker(locker)

func NewServiceProvider

func NewServiceProvider() di.ServiceProvider

NewServiceProvider trả về một ServiceProvider mới cho module scheduler.

Hàm này khởi tạo và trả về một đối tượng ServiceProvider để sử dụng với DI container. ServiceProvider cho phép tự động đăng ký và cấu hình scheduler manager cho ứng dụng.

Returns:

  • di.ServiceProvider: Interface di.ServiceProvider đã được implement bởi ServiceProvider

Example:

app.Register(scheduler.NewServiceProvider())

Types

type Config added in v0.0.5

type Config struct {
	// AutoStart xác định có tự động khởi động scheduler khi ứng dụng boot không
	// ServiceProvider sẽ tự động gọi scheduler.StartAsync() trong Boot() method nếu true
	AutoStart bool `mapstructure:"auto_start" yaml:"auto_start"`

	// DistributedLock chứa cấu hình cho distributed locking
	DistributedLock DistributedLockConfig `mapstructure:"distributed_lock" yaml:"distributed_lock"`

	// Options chứa cấu hình RedisLockerOptions cho distributed locking
	Options RedisLockerOptions `mapstructure:"options" yaml:"options"`
}

Config là cấu trúc cấu hình chính cho scheduler provider.

Config định nghĩa các tùy chọn cấu hình cho scheduler manager và distributed locking. Nó hỗ trợ Redis distributed locking khi chạy trên nhiều instance.

func DefaultConfig added in v0.0.5

func DefaultConfig() Config

DefaultConfig trả về cấu hình mặc định cho scheduler.

type DistributedLockConfig added in v0.0.5

type DistributedLockConfig struct {
	// Enabled xác định có bật distributed locking không
	// Chỉ cần thiết khi chạy scheduler trên nhiều instance trong môi trường phân tán
	Enabled bool `mapstructure:"enabled" yaml:"enabled"`
}

DistributedLockConfig chứa cấu hình cho distributed locking.

type Manager

type Manager interface {
	// WithDistributedLocker thiết lập distributed locker (như Redis) cho scheduler.
	// Hữu ích khi chạy scheduler trên nhiều máy chủ trong môi trường phân tán.
	WithDistributedLocker(locker gocron.Locker) Manager

	// Every tạo một công việc mới với khoảng thời gian được chỉ định.
	// Trả về Manager để hỗ trợ fluent interface.
	Every(interval interface{}) Manager

	// Second chỉ định đơn vị thời gian là giây (đơn lẻ).
	// Trả về Manager để hỗ trợ fluent interface.
	Second() Manager

	// Seconds chỉ định đơn vị thời gian là giây.
	// Trả về Manager để hỗ trợ fluent interface.
	Seconds() Manager

	// Minutes chỉ định đơn vị thời gian là phút.
	// Trả về Manager để hỗ trợ fluent interface.
	Minutes() Manager

	// Hours chỉ định đơn vị thời gian là giờ.
	// Trả về Manager để hỗ trợ fluent interface.
	Hours() Manager

	// Days chỉ định đơn vị thời gian là ngày.
	// Trả về Manager để hỗ trợ fluent interface.
	Days() Manager

	// Weeks chỉ định đơn vị thời gian là tuần.
	// Trả về Manager để hỗ trợ fluent interface.
	Weeks() Manager

	// At chỉ định thời điểm trong ngày để chạy công việc.
	// Định dạng: "HH:MM" hoặc "HH:MM:SS".
	// Trả về Manager để hỗ trợ fluent interface.
	At(time string) Manager

	// StartAt chỉ định thời điểm bắt đầu cho công việc.
	// Trả về Manager để hỗ trợ fluent interface.
	StartAt(time time.Time) Manager

	// Cron thiết lập biểu thức cron cho công việc.
	// Trả về Manager để hỗ trợ fluent interface.
	Cron(cronExpression string) Manager

	// CronWithSeconds thiết lập biểu thức cron có hỗ trợ giây.
	// Trả về Manager để hỗ trợ fluent interface.
	CronWithSeconds(cronExpression string) Manager

	// Tag đánh dấu công việc với các tag được chỉ định.
	// Trả về Manager để hỗ trợ fluent interface.
	Tag(tags ...string) Manager

	// SingletonMode đặt công việc ở chế độ singleton (không chạy đồng thời).
	// Trả về Manager để hỗ trợ fluent interface.
	SingletonMode() Manager

	// Do đặt hàm để thực thi cho công việc với các tham số tùy chọn.
	// Trả về Job và error nếu có.
	Do(jobFun interface{}, params ...interface{}) (*gocron.Job, error)

	// Name đặt tên cho công việc đang được cấu hình.
	// Trả về Manager để hỗ trợ fluent interface.
	Name(name string) Manager

	// RemoveByTag xóa các công việc theo tag.
	RemoveByTag(tag string) error

	// RemoveByTags xóa các công việc khớp với TẤT CẢ tags đã chỉ định.
	RemoveByTags(tags ...string) error

	// FindJobsByTag tìm công việc theo tag.
	FindJobsByTag(tags ...string) ([]*gocron.Job, error)

	// StartAsync bắt đầu scheduler trong một goroutine riêng.
	StartAsync()

	// StartBlocking bắt đầu scheduler và chặn luồng hiện tại.
	StartBlocking()

	// Stop dừng scheduler.
	Stop()

	// IsRunning kiểm tra xem scheduler có đang chạy không.
	IsRunning() bool

	// Clear xóa tất cả các công việc đã đăng ký.
	Clear()

	// GetScheduler trả về đối tượng scheduler gốc của gocron.
	GetScheduler() *gocron.Scheduler

	// RegisterEventListeners đăng ký các listener cho các sự kiện.
	RegisterEventListeners(eventListeners ...gocron.EventListener)
}

Manager là interface chính cho việc quản lý lịch trình công việc, wrapping gocron.

func NewScheduler

func NewScheduler(cfg ...Config) Manager

NewScheduler tạo một đối tượng Manager mới sử dụng gocron làm backend. Nhận tham số config để cấu hình scheduler.

func NewSchedulerWithConfig added in v0.0.5

func NewSchedulerWithConfig(cfg Config) Manager

NewSchedulerWithConfig tạo một đối tượng Manager mới với cấu hình cụ thể.

type RedisLockerOptions

type RedisLockerOptions struct {
	// KeyPrefix là tiền tố được thêm vào trước mỗi khóa trong Redis
	KeyPrefix string `mapstructure:"key_prefix" yaml:"key_prefix"`

	// LockDuration là thời gian một khóa sẽ tồn tại trước khi tự động hết hạn (giây)
	LockDuration int `mapstructure:"lock_duration" yaml:"lock_duration"`

	// MaxRetries là số lần thử tối đa khi gặp lỗi khi tương tác với Redis
	MaxRetries int `mapstructure:"max_retries" yaml:"max_retries"`

	// RetryDelay là thời gian chờ giữa các lần thử (milliseconds)
	RetryDelay int `mapstructure:"retry_delay" yaml:"retry_delay"`
}

RedisLockerOptions chứa các tùy chọn cấu hình cho Redis Locker.

func DefaultRedisLockerOptions

func DefaultRedisLockerOptions() RedisLockerOptions

DefaultRedisLockerOptions trả về các tùy chọn mặc định cho Redis Locker.

func (RedisLockerOptions) ToTimeDuration added in v0.0.5

func (opts RedisLockerOptions) ToTimeDuration() RedisLockerOptionsTime

ToTimeDuration chuyển đổi các giá trị int trong config thành time.Duration.

type RedisLockerOptionsTime added in v0.0.5

type RedisLockerOptionsTime struct {
	// KeyPrefix là tiền tố được thêm vào trước mỗi khóa trong Redis
	KeyPrefix string

	// LockDuration là thời gian một khóa sẽ tồn tại trước khi tự động hết hạn
	LockDuration time.Duration

	// MaxRetries là số lần thử tối đa khi gặp lỗi khi tương tác với Redis
	MaxRetries int

	// RetryDelay là thời gian chờ giữa các lần thử
	RetryDelay time.Duration
}

RedisLockerOptionsTime chứa các tùy chọn cấu hình với time.Duration.

type ServiceProvider

type ServiceProvider struct {
	// contains filtered or unexported fields
}

ServiceProvider cung cấp dịch vụ scheduler và tích hợp với DI container.

ServiceProvider là một implementation của interface di.ServiceProvider, cho phép tự động đăng ký scheduler manager vào DI container của ứng dụng. ServiceProvider thực hiện công việc:

  • Tạo một scheduler manager mới sử dụng gocron
  • Đăng ký scheduler manager vào DI container với key "scheduler"

Việc cấu hình cụ thể và đăng ký các task được thực hiện bởi ứng dụng.

Để sử dụng ServiceProvider, ứng dụng cần:

  • Implement interface Container() *di.Container để cung cấp DI container

func (*ServiceProvider) Boot

func (p *ServiceProvider) Boot(app interface{})

Boot được gọi sau khi tất cả các service provider đã được đăng ký.

Boot là một lifecycle hook của di.ServiceProvider mà thực hiện sau khi tất cả các service provider đã được đăng ký xong.

Trong trường hợp của SchedulerServiceProvider, có thể dùng Boot để: 1. Lấy scheduler manager từ container 2. Bắt đầu scheduler trong chế độ async để nó sẵn sàng xử lý các task

Params:

  • app: interface{} - Đối tượng ứng dụng phải implement interface: Container() *di.Container - Trả về DI container

func (*ServiceProvider) Providers added in v0.0.5

func (p *ServiceProvider) Providers() []string

func (*ServiceProvider) Register

func (p *ServiceProvider) Register(app interface{})

Register đăng ký scheduler vào DI container.

Register được gọi khi đăng ký ServiceProvider vào ứng dụng. Phương thức này tạo một scheduler manager mới và đăng ký vào DI container của ứng dụng.

Params:

  • app: interface{} - Đối tượng ứng dụng phải implement interface: Container() *di.Container - Trả về DI container

Luồng thực thi:

  1. Kiểm tra app có implement Container() không, nếu không thì return
  2. Lấy container từ app, kiểm tra nếu nil thì panic
  3. Tạo scheduler manager mới
  4. Đăng ký scheduler manager vào container với key "scheduler"

Việc cấu hình và đăng ký các task sẽ được thực hiện bởi ứng dụng, cho phép mỗi ứng dụng tùy chỉnh scheduler theo nhu cầu riêng.

func (*ServiceProvider) Requires added in v0.0.5

func (p *ServiceProvider) Requires() []string

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL