-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: improve xsched package with better error handling and code …
…organization
- Loading branch information
Showing
3 changed files
with
754 additions
and
105 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,65 +1,163 @@ | ||
package main | ||
|
||
import ( | ||
"os" | ||
"os/signal" | ||
"strings" | ||
"syscall" | ||
"time" | ||
|
||
"github.com/seefs001/xox/xcolor" | ||
"github.com/seefs001/xox/xsched" | ||
) | ||
|
||
// CronExample represents a cron job example | ||
type CronExample struct { | ||
name string | ||
spec string | ||
description string | ||
color xcolor.ColorCode | ||
} | ||
|
||
func main() { | ||
c := xsched.New() | ||
|
||
xcolor.Println(xcolor.Bold, "Starting Scheduler Example...") | ||
|
||
// Add a job that runs every second | ||
id1, _ := c.AddEverySecond(func() { | ||
xcolor.Println(xcolor.Green, "[Every Second] Executed at: %s", time.Now().Format("15:04:05")) | ||
}) | ||
|
||
// Add a job that runs every 5 seconds | ||
id2, _ := c.AddFunc("*/5 * * * * *", func() { | ||
xcolor.Println(xcolor.Cyan, "[Every 5 Seconds] Executed at: %s", time.Now().Format("15:04:05")) | ||
}) | ||
|
||
// Add a job that runs every minute | ||
id3, _ := c.AddEveryMinute(func() { | ||
xcolor.Println(xcolor.Yellow, "[Every Minute] Executed at: %s", time.Now().Format("15:04:05")) | ||
}) | ||
|
||
// Add a job that runs at 30 seconds past each minute | ||
id4, _ := c.AddFunc("30 * * * * *", func() { | ||
xcolor.Println(xcolor.Blue, "[At 30 Seconds] Executed at: %s", time.Now().Format("15:04:05")) | ||
}) | ||
|
||
xcolor.Println(xcolor.White, "Jobs added successfully with IDs:") | ||
xcolor.Println(xcolor.White, "ID1: %s", id1) | ||
xcolor.Println(xcolor.White, "ID2: %s", id2) | ||
xcolor.Println(xcolor.White, "ID3: %s", id3) | ||
xcolor.Println(xcolor.White, "ID4: %s", id4) | ||
|
||
c.Start() | ||
xcolor.Println(xcolor.Bold, "Scheduler started") | ||
|
||
// Wait for 35 seconds to allow jobs to run | ||
xcolor.Println(xcolor.White, "Waiting for 35 seconds...") | ||
start := time.Now() | ||
for time.Since(start) < 35*time.Second { | ||
time.Sleep(time.Second) | ||
elapsed := int(time.Since(start).Seconds()) | ||
progressBar := xcolor.SprintMulti([]xcolor.ColorCode{xcolor.Purple}, "["+strings.Repeat("=", elapsed)+strings.Repeat(" ", 35-elapsed)+"]") | ||
xcolor.Print(xcolor.White, "\rElapsed: %2d seconds %s", elapsed, progressBar) | ||
xcolor.Println(xcolor.Bold, "Starting Advanced Scheduler Example...") | ||
|
||
scheduler := xsched.New() | ||
|
||
// Define cron examples with different expressions | ||
examples := []CronExample{ | ||
{ | ||
name: "Immediate and Every Second", | ||
spec: "* * * * * *", | ||
description: "Runs immediately and then every second", | ||
color: xcolor.Green, | ||
}, | ||
{ | ||
name: "Immediate and Every 5 Seconds", | ||
spec: "*/5 * * * * *", | ||
description: "Runs immediately and then every 5 seconds", | ||
color: xcolor.Cyan, | ||
}, | ||
{ | ||
name: "Every Minute", | ||
spec: "0 * * * * *", | ||
description: "Runs at the start of every minute", | ||
color: xcolor.Yellow, | ||
}, | ||
{ | ||
name: "At 30 Seconds", | ||
spec: "30 * * * * *", | ||
description: "Runs at 30th second of every minute", | ||
color: xcolor.Blue, | ||
}, | ||
{ | ||
name: "Work Hours", | ||
spec: "0 0 9-17 * * 1-5", | ||
description: "Runs at the start of every hour during work hours (9-17) on weekdays", | ||
color: xcolor.Purple, | ||
}, | ||
{ | ||
name: "Multiple Times", | ||
spec: "0,15,30,45 * * * * *", | ||
description: "Runs at 0,15,30,45 seconds of every minute", | ||
color: xcolor.Red, | ||
}, | ||
} | ||
|
||
// Print cron expression guide | ||
printCronGuide() | ||
|
||
// Add jobs and print their details | ||
xcolor.Println(xcolor.Bold, "\nConfigured Jobs:") | ||
xcolor.Println(xcolor.White, "%-25s %-20s %s", "Name", "Expression", "Description") | ||
xcolor.Println(xcolor.White, strings.Repeat("-", 80)) | ||
|
||
jobIDs := make(map[string]string) | ||
for _, ex := range examples { | ||
id, err := scheduler.AddFuncWithOptions(ex.spec, createColoredJob(ex.name, ex.color), true) | ||
if err != nil { | ||
xcolor.Println(xcolor.Red, "Failed to add job '%s': %v", ex.name, err) | ||
continue | ||
} | ||
jobIDs[ex.name] = id | ||
xcolor.Println(ex.color, "%-25s %-20s %s", ex.name, ex.spec, ex.description) | ||
} | ||
xcolor.Println(xcolor.White, "\n") | ||
|
||
// Remove the every-second job | ||
c.Remove(id1) | ||
xcolor.Println(xcolor.Yellow, "Job ID1 removed") | ||
// Start the scheduler | ||
scheduler.Start() | ||
xcolor.Println(xcolor.Bold, "\nScheduler started") | ||
|
||
// Wait for 5 more seconds | ||
time.Sleep(5 * time.Second) | ||
// Setup signal handling for graceful shutdown | ||
sigChan := make(chan os.Signal, 1) | ||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM) | ||
|
||
c.Stop() | ||
// Start progress monitoring | ||
startTime := time.Now() | ||
go monitorProgress(startTime) | ||
|
||
xcolor.Println(xcolor.White, "\nPress Ctrl+C to exit") | ||
<-sigChan | ||
|
||
// Graceful shutdown | ||
xcolor.Println(xcolor.Yellow, "\n\nGracefully shutting down...") | ||
scheduler.Stop() | ||
xcolor.Println(xcolor.Red, "Scheduler stopped") | ||
} | ||
|
||
func createColoredJob(name string, color xcolor.ColorCode) func() { | ||
return func() { | ||
now := time.Now() | ||
xcolor.Println(color, "[%s] Executed at: %s.%03d", | ||
name, | ||
now.Format("15:04:05"), | ||
now.Nanosecond()/1000000) | ||
} | ||
} | ||
|
||
func monitorProgress(startTime time.Time) { | ||
for { | ||
time.Sleep(time.Second) | ||
elapsed := int(time.Since(startTime).Seconds()) | ||
progressBar := createColoredProgressBar(elapsed, 60) | ||
xcolor.Print(xcolor.White, "\rRunning time: %2d seconds %s", | ||
elapsed, | ||
progressBar) | ||
} | ||
} | ||
|
||
func createColoredProgressBar(current, total int) string { | ||
progress := current % total | ||
bar := strings.Builder{} | ||
bar.WriteString("[") | ||
for i := 0; i < total; i++ { | ||
if i < progress { | ||
bar.WriteString("=") | ||
} else if i == progress { | ||
bar.WriteString(">") | ||
} else { | ||
bar.WriteString(" ") | ||
} | ||
} | ||
bar.WriteString("]") | ||
return xcolor.SprintMulti([]xcolor.ColorCode{xcolor.Purple}, bar.String()) | ||
} | ||
func printCronGuide() { | ||
guide := ` | ||
Cron Expression Format: | ||
┌──────── Second (0-59) | ||
│ ┌────── Minute (0-59) | ||
│ │ ┌──── Hour (0-23) | ||
│ │ │ ┌── Day of Month (1-31) | ||
│ │ │ │ ┌ Month (1-12) | ||
│ │ │ │ │ ┌─ Day of Week (0-6) (Sunday=0) | ||
* * * * * * | ||
Special Characters: | ||
* - Every unit | ||
*/n - Every n units | ||
n-m - Range from n to m | ||
n,m,k - Specific values | ||
n-m/k - Every k units between n-m | ||
` | ||
xcolor.Println(xcolor.Cyan, guide) | ||
} |
Oops, something went wrong.