github.com/goravel/framework@v1.13.9/schedule/application.go (about)

     1  package schedule
     2  
     3  import (
     4  	"time"
     5  
     6  	"github.com/gookit/color"
     7  	"github.com/robfig/cron/v3"
     8  
     9  	"github.com/goravel/framework/contracts/cache"
    10  	"github.com/goravel/framework/contracts/console"
    11  	"github.com/goravel/framework/contracts/log"
    12  	"github.com/goravel/framework/contracts/schedule"
    13  	"github.com/goravel/framework/support/carbon"
    14  )
    15  
    16  type Application struct {
    17  	artisan console.Artisan
    18  	cache   cache.Cache
    19  	cron    *cron.Cron
    20  	log     log.Log
    21  }
    22  
    23  func NewApplication(artisan console.Artisan, cache cache.Cache, log log.Log) *Application {
    24  	return &Application{
    25  		artisan: artisan,
    26  		cache:   cache,
    27  		log:     log,
    28  	}
    29  }
    30  
    31  func (app *Application) Call(callback func()) schedule.Event {
    32  	return NewCallbackEvent(callback)
    33  }
    34  
    35  func (app *Application) Command(command string) schedule.Event {
    36  	return NewCommandEvent(command)
    37  }
    38  
    39  func (app *Application) Register(events []schedule.Event) {
    40  	if app.cron == nil {
    41  		app.cron = cron.New(cron.WithLogger(NewLogger(app.log)))
    42  	}
    43  
    44  	app.addEvents(events)
    45  }
    46  
    47  func (app *Application) Run() {
    48  	app.cron.Run()
    49  }
    50  
    51  func (app *Application) addEvents(events []schedule.Event) {
    52  	for _, event := range events {
    53  		chain := cron.NewChain(cron.Recover(NewLogger(app.log)))
    54  		if event.GetDelayIfStillRunning() {
    55  			chain = cron.NewChain(cron.DelayIfStillRunning(NewLogger(app.log)), cron.Recover(NewLogger(app.log)))
    56  		} else if event.GetSkipIfStillRunning() {
    57  			chain = cron.NewChain(cron.SkipIfStillRunning(NewLogger(app.log)), cron.Recover(NewLogger(app.log)))
    58  		}
    59  		_, err := app.cron.AddJob(event.GetCron(), chain.Then(app.getJob(event)))
    60  
    61  		if err != nil {
    62  			app.log.Errorf("add schedule error: %v", err)
    63  		}
    64  	}
    65  }
    66  
    67  func (app *Application) getJob(event schedule.Event) cron.Job {
    68  	return cron.FuncJob(func() {
    69  		if event.IsOnOneServer() && event.GetName() != "" {
    70  			if app.cache.Lock(event.GetName()+carbon.Now().Format("Hi"), 1*time.Hour).Get() {
    71  				app.runJob(event)
    72  			}
    73  		} else {
    74  			app.runJob(event)
    75  		}
    76  	})
    77  }
    78  
    79  func (app *Application) runJob(event schedule.Event) {
    80  	if event.GetCommand() != "" {
    81  		app.artisan.Call(event.GetCommand())
    82  	} else {
    83  		event.GetCallback()()
    84  	}
    85  }
    86  
    87  type Logger struct {
    88  	log log.Log
    89  }
    90  
    91  func NewLogger(log log.Log) *Logger {
    92  	return &Logger{
    93  		log: log,
    94  	}
    95  }
    96  
    97  func (log *Logger) Info(msg string, keysAndValues ...any) {
    98  	color.Green.Printf("%s %v\n", msg, keysAndValues)
    99  }
   100  
   101  func (log *Logger) Error(err error, msg string, keysAndValues ...any) {
   102  	log.log.Error(msg, keysAndValues)
   103  }