mirror of
https://github.com/ditatompel/xmr-remote-nodes.git
synced 2025-01-08 05:52:10 +07:00
Make sure cron goroutine is stopped
Adding struct chan to run cron Process to stop the goroutine. Moving db migration inside `fiber.IsChild` block to avoid multiple execution migration script when in prefork mode. Give additional time for graceful shutdown.
This commit is contained in:
parent
8c1f6b0c43
commit
40b9a6e1d6
2 changed files with 52 additions and 42 deletions
|
@ -6,6 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
"time"
|
||||||
"xmr-remote-nodes/frontend"
|
"xmr-remote-nodes/frontend"
|
||||||
"xmr-remote-nodes/handler"
|
"xmr-remote-nodes/handler"
|
||||||
"xmr-remote-nodes/internal/config"
|
"xmr-remote-nodes/internal/config"
|
||||||
|
@ -22,7 +23,7 @@ import (
|
||||||
|
|
||||||
var serveCmd = &cobra.Command{
|
var serveCmd = &cobra.Command{
|
||||||
Use: "serve",
|
Use: "serve",
|
||||||
Short: "Serve the WebUI",
|
Short: "Serve the WebUI and APIs",
|
||||||
Long: `This command will run HTTP server for APIs and WebUI.`,
|
Long: `This command will run HTTP server for APIs and WebUI.`,
|
||||||
Run: func(_ *cobra.Command, _ []string) {
|
Run: func(_ *cobra.Command, _ []string) {
|
||||||
serve()
|
serve()
|
||||||
|
@ -31,14 +32,26 @@ var serveCmd = &cobra.Command{
|
||||||
|
|
||||||
func serve() {
|
func serve() {
|
||||||
appCfg := config.AppCfg()
|
appCfg := config.AppCfg()
|
||||||
// connect to DB
|
|
||||||
if err := database.ConnectDB(); err != nil {
|
if err := database.ConnectDB(); err != nil {
|
||||||
panic(err)
|
slog.Error(fmt.Sprintf("[DB] %s", err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// signal channel to capture system calls
|
||||||
|
sigCh := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT)
|
||||||
|
|
||||||
|
stopCron := make(chan struct{})
|
||||||
|
if !fiber.IsChild() {
|
||||||
// run db migrations
|
// run db migrations
|
||||||
if err := database.MigrateDb(database.GetDB()); err != nil {
|
if err := database.MigrateDb(database.GetDB()); err != nil {
|
||||||
panic(err)
|
slog.Error(fmt.Sprintf("[DB] %s", err.Error()))
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// run cron process
|
||||||
|
cronRepo := cron.New()
|
||||||
|
go cronRepo.RunCronProcess(stopCron)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define Fiber config & app.
|
// Define Fiber config & app.
|
||||||
|
@ -67,28 +80,21 @@ func serve() {
|
||||||
// NotFoundFile: "index.html",
|
// NotFoundFile: "index.html",
|
||||||
}))
|
}))
|
||||||
|
|
||||||
// signal channel to capture system calls
|
// go routine to capture system calls
|
||||||
sigCh := make(chan os.Signal, 1)
|
|
||||||
signal.Notify(sigCh, syscall.SIGTERM, syscall.SIGINT, syscall.SIGQUIT)
|
|
||||||
|
|
||||||
// start a cleanup cron-job
|
|
||||||
if !fiber.IsChild() {
|
|
||||||
cronRepo := cron.New()
|
|
||||||
go cronRepo.RunCronProcess()
|
|
||||||
}
|
|
||||||
|
|
||||||
// start shutdown goroutine
|
|
||||||
go func() {
|
go func() {
|
||||||
// capture sigterm and other system call here
|
|
||||||
<-sigCh
|
<-sigCh
|
||||||
|
close(stopCron) // stop cron goroutine
|
||||||
slog.Info("Shutting down HTTP server...")
|
slog.Info("Shutting down HTTP server...")
|
||||||
_ = app.Shutdown()
|
_ = app.Shutdown()
|
||||||
|
|
||||||
|
// give time for graceful shutdown
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
}()
|
}()
|
||||||
|
|
||||||
// start http server
|
// start http server
|
||||||
serverAddr := fmt.Sprintf("%s:%d", appCfg.Host, appCfg.Port)
|
serverAddr := fmt.Sprintf("%s:%d", appCfg.Host, appCfg.Port)
|
||||||
if err := app.Listen(serverAddr); err != nil {
|
if err := app.Listen(serverAddr); err != nil {
|
||||||
slog.Error(fmt.Sprintf("Server is not running! error: %v", err))
|
slog.Error(fmt.Sprintf("[HTTP] Server is not running! error: %v", err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type CronRepository interface {
|
type CronRepository interface {
|
||||||
RunCronProcess()
|
RunCronProcess(chan struct{})
|
||||||
Crons() ([]Cron, error)
|
Crons() ([]Cron, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,9 +36,10 @@ func New() CronRepository {
|
||||||
return &CronRepo{db: database.GetDB()}
|
return &CronRepo{db: database.GetDB()}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *CronRepo) RunCronProcess() {
|
func (r *CronRepo) RunCronProcess(c chan struct{}) {
|
||||||
for {
|
for {
|
||||||
time.Sleep(60 * time.Second)
|
select {
|
||||||
|
case <-time.After(60 * time.Second):
|
||||||
slog.Info("[CRON] Running cron cycle...")
|
slog.Info("[CRON] Running cron cycle...")
|
||||||
list, err := r.queueList()
|
list, err := r.queueList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -55,7 +56,6 @@ func (r *CronRepo) RunCronProcess() {
|
||||||
}
|
}
|
||||||
|
|
||||||
r.preRunTask(task.ID, currentTs)
|
r.preRunTask(task.ID, currentTs)
|
||||||
|
|
||||||
r.execCron(task.Slug)
|
r.execCron(task.Slug)
|
||||||
|
|
||||||
runTime := math.Ceil(time.Since(startTime).Seconds()*1000) / 1000
|
runTime := math.Ceil(time.Since(startTime).Seconds()*1000) / 1000
|
||||||
|
@ -65,6 +65,10 @@ func (r *CronRepo) RunCronProcess() {
|
||||||
r.postRunTask(task.ID, nextRun, runTime)
|
r.postRunTask(task.ID, nextRun, runTime)
|
||||||
}
|
}
|
||||||
slog.Info("[CRON] Cron cycle done!")
|
slog.Info("[CRON] Cron cycle done!")
|
||||||
|
case <-c:
|
||||||
|
slog.Info("[CRON] Shutting down cron...")
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue