Yimaru-BackEnd/internal/web_server/cron.go

355 lines
11 KiB
Go
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package httpserver
import (
"context"
"os"
"time"
"log"
"github.com/SamuelTariku/FortuneBet-Backend/internal/domain"
betSvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/bet"
enetpulse "github.com/SamuelTariku/FortuneBet-Backend/internal/services/enet_pulse"
eventsvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/event"
notificationservice "github.com/SamuelTariku/FortuneBet-Backend/internal/services/notification"
oddssvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/odds"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/report"
resultsvc "github.com/SamuelTariku/FortuneBet-Backend/internal/services/result"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/ticket"
"github.com/SamuelTariku/FortuneBet-Backend/internal/services/virtualGame/veli"
"github.com/robfig/cron/v3"
"go.uber.org/zap"
)
func StartDataFetchingCrons(eventService eventsvc.Service, oddsService oddssvc.ServiceImpl, resultService *resultsvc.Service, mongoLogger *zap.Logger) {
c := cron.New(cron.WithSeconds())
schedule := []struct {
spec string
task func()
}{
{
spec: "0 0 * * * *", // Every 1 hour
task: func() {
mongoLogger.Info("Began fetching upcoming events cron task")
if err := eventService.FetchUpcomingEvents(context.Background()); err != nil {
mongoLogger.Error("Failed to fetch upcoming events",
zap.Error(err),
)
} else {
mongoLogger.Info("Completed fetching upcoming events without errors")
}
},
},
{
spec: "0 0 * * * *", // Every 1 hour (since its takes that long to fetch all the events)
task: func() {
mongoLogger.Info("Began fetching non live odds cron task")
if err := oddsService.FetchNonLiveOdds(context.Background()); err != nil {
mongoLogger.Error("Failed to fetch non live odds",
zap.Error(err),
)
} else {
mongoLogger.Info("Completed fetching non live odds without errors")
}
},
},
{
spec: "0 */5 * * * *", // Every 5 Minutes
task: func() {
mongoLogger.Info("Began update all expired events status cron task")
if _, err := resultService.CheckAndUpdateExpiredB365Events(context.Background()); err != nil {
mongoLogger.Error("Failed to update expired events status",
zap.Error(err),
)
} else {
mongoLogger.Info("Completed expired events without errors")
}
},
},
{
spec: "0 */15 * * * *", // Every 15 Minutes
task: func() {
mongoLogger.Info("Began updating bets based on event results cron task")
if err := resultService.FetchB365ResultAndUpdateBets(context.Background()); err != nil {
mongoLogger.Error("Failed to process result",
zap.Error(err),
)
} else {
mongoLogger.Info("Completed processing all event result outcomes without errors")
}
},
},
{
spec: "0 0 0 * * 1", // Every Monday
task: func() {
mongoLogger.Info("Began Send weekly result notification cron task")
if err := resultService.CheckAndSendResultNotifications(context.Background(), time.Now().Add(-7*24*time.Hour)); err != nil {
mongoLogger.Error("Failed to process result",
zap.Error(err),
)
} else {
mongoLogger.Info("Completed sending weekly result notification without errors")
}
},
},
}
for _, job := range schedule {
// job.task()
if _, err := c.AddFunc(job.spec, job.task); err != nil {
mongoLogger.Error("Failed to schedule data fetching cron job",
zap.Error(err),
)
}
}
c.Start()
log.Println("Cron jobs started for event and odds services")
mongoLogger.Info("Cron jobs started for event and odds services")
}
func StartCleanupCrons(ticketService ticket.Service, notificationSvc *notificationservice.Service, mongoLogger *zap.Logger) {
c := cron.New(cron.WithSeconds())
schedule := []struct {
spec string
task func()
}{
{
spec: "0 0 * * * *", // Every hour
task: func() {
mongoLogger.Info("Deleting old tickets")
if err := ticketService.DeleteOldTickets(context.Background()); err != nil {
mongoLogger.Error("Failed to remove old ticket",
zap.Error(err),
)
} else {
mongoLogger.Info("Successfully deleted old tickets")
}
},
},
{
spec: "0 0 0 * * 1", // Every Monday (Weekly)
task: func() {
mongoLogger.Info("Deleting old notifications")
if err := notificationSvc.DeleteOldNotifications(context.Background()); err != nil {
mongoLogger.Error("Failed to remove old notifications",
zap.Error(err),
)
} else {
mongoLogger.Info("Successfully deleted old notifications")
}
},
},
}
for _, job := range schedule {
if _, err := c.AddFunc(job.spec, job.task); err != nil {
mongoLogger.Error("Failed to schedule ticket cron job",
zap.Error(err),
)
}
}
c.Start()
mongoLogger.Info("Cron jobs started for ticket service")
}
// SetupReportCronJobs schedules periodic report generation
func SetupReportandVirtualGameCronJobs(
ctx context.Context,
reportService *report.Service,
virtualGameService *veli.Service, // inject your virtual game service
outputDir string,
) {
c := cron.New(cron.WithSeconds()) // use WithSeconds for testing
schedule := []struct {
spec string
period string
}{
// {
// spec: "*/60 * * * * *", // Every 1 minute for testing
// period: "test",
// },
{
spec: "0 0 0 * * *", // Daily at midnight
period: "daily",
},
}
for _, job := range schedule {
period := job.period
if _, err := c.AddFunc(job.spec, func() {
log.Printf("[%s] Running virtual game fetch & store job...", period)
brandID := os.Getenv("VELI_BRAND_ID")
if brandID == "" {
log.Println("VELI_BRAND_ID not set, skipping virtual game sync")
return
}
req := domain.ProviderRequest{
BrandID: brandID,
ExtraData: true,
Size: 1000,
Page: 1,
}
allGames, err := virtualGameService.FetchAndStoreAllVirtualGames(ctx, req, "ETB")
if err != nil {
log.Printf("[%s] Error fetching/storing virtual games: %v", period, err)
return
}
log.Printf("[%s] Successfully fetched & stored %d virtual games", period, len(allGames))
// --- Generate reports only for daily runs ---
if period == "daily" {
now := time.Now()
from := time.Date(now.Year(), now.Month(), now.Day()-1, 0, 0, 0, 0, now.Location())
to := time.Date(now.Year(), now.Month(), now.Day()-1, 23, 59, 59, 0, now.Location())
log.Printf("Running daily report for period %s -> %s", from.Format(time.RFC3339), to.Format(time.RFC3339))
if err := reportService.GenerateReport(ctx, from, to); err != nil {
log.Printf("Error generating daily report: %v", err)
} else {
log.Printf("Successfully generated daily report")
}
}
}); err != nil {
log.Fatalf("Failed to schedule %s cron job: %v", period, err)
}
}
c.Start()
log.Printf("Cron jobs started. Reports will be saved to: %s", outputDir)
}
func ProcessBetCashback(ctx context.Context, betService *betSvc.Service) {
c := cron.New(cron.WithSeconds())
schedule := []struct {
spec string
task func()
}{
{
spec: "0 0 0 * * *", // Daily at midnight
task: func() {
log.Println("process bet cashbacks...")
if err := betService.ProcessBetCashback(ctx); err != nil {
log.Printf("Failed to process bet cashbacks: %v", err)
} else {
log.Printf("Successfully processed bet cashbacks")
}
},
},
}
for _, job := range schedule {
if _, err := c.AddFunc(job.spec, job.task); err != nil {
log.Fatalf("Failed to schedule cron job: %v", err)
}
}
c.Start()
log.Println("Cron jobs started for bet cashbacks")
}
func StartEnetPulseCron(enetPulseSvc *enetpulse.Service, mongoLogger *zap.Logger) {
c := cron.New(cron.WithSeconds())
schedule := []struct {
spec string
task func()
}{
{
spec: "0 0 */2 * * *", // Every 2 hours
task: func() {
ctx := context.Background()
// 1⃣ Sports
mongoLogger.Info("Began fetching and storing sports cron task")
if err := enetPulseSvc.FetchAndStoreSports(ctx); err != nil {
mongoLogger.Error("Failed to fetch and store sports", zap.Error(err))
} else {
mongoLogger.Info("\n\n✅ Completed fetching and storing sports\n\n")
}
// 2⃣ Tournament Templates
mongoLogger.Info("Began fetching and storing tournament templates cron task")
if err := enetPulseSvc.FetchAndStoreTournamentTemplates(ctx); err != nil {
mongoLogger.Error("Failed to fetch and store tournament templates", zap.Error(err))
} else {
mongoLogger.Info("\n\n✅ Completed fetching and storing tournament templates\n\n")
}
// 3⃣ Tournaments
mongoLogger.Info("Began fetching and storing tournaments cron task")
if err := enetPulseSvc.FetchAndStoreTournaments(ctx); err != nil {
mongoLogger.Error("Failed to fetch and store tournaments", zap.Error(err))
} else {
mongoLogger.Info("\n\n✅ Completed fetching and storing tournaments\n\n")
}
// 4⃣ Tournament Stages
mongoLogger.Info("Began fetching and storing tournament stages cron task")
if err := enetPulseSvc.FetchAndStoreTournamentStages(ctx); err != nil {
mongoLogger.Error("Failed to fetch and store tournament stages", zap.Error(err))
} else {
mongoLogger.Info("✅ \n\nCompleted fetching and storing tournament stages\n\n")
}
// // 5⃣ Fixtures
mongoLogger.Info("Began fetching and storing fixtures cron task")
today := time.Now().Format("2006-01-02")
if err := enetPulseSvc.FetchAndStoreFixtures(ctx, today); err != nil {
mongoLogger.Error("Failed to fetch and store fixtures", zap.Error(err))
} else {
mongoLogger.Info("\n\n✅ Completed fetching and storing fixtures\n\n")
}
// 6⃣ Results
mongoLogger.Info("Began fetching and storing results cron task")
if err := enetPulseSvc.FetchAndStoreResults(ctx); err != nil {
mongoLogger.Error("Failed to fetch and store results", zap.Error(err))
} else {
mongoLogger.Info("\n\n✅ Completed fetching and storing results\n\n")
}
// 7 Outcome Types
mongoLogger.Info("Began fetching and storing outcome_types cron task")
if err := enetPulseSvc.FetchAndStoreOutcomeTypes(ctx); err != nil {
mongoLogger.Error("Failed to fetch and store outcome_types", zap.Error(err))
} else {
mongoLogger.Info("\n\n✅ Completed fetching and storing outcome_types\n\n")
}
// 8 Preodds
mongoLogger.Info("Began fetching and storing preodds cron task")
if err := enetPulseSvc.FetchAndStorePreodds(ctx); err != nil {
mongoLogger.Error("Failed to fetch and store preodds", zap.Error(err))
} else {
mongoLogger.Info("\n\n✅ Completed fetching and storing preodds\n\n")
}
},
},
}
for _, job := range schedule {
// Run immediately at startup
job.task()
// Schedule the task
if _, err := c.AddFunc(job.spec, job.task); err != nil {
mongoLogger.Error("Failed to schedule EnetPulse cron job", zap.Error(err))
}
}
c.Start()
log.Println("EnetPulse cron jobs started for sports, tournament templates, tournaments, tournament stages, fixtures, and results")
mongoLogger.Info("EnetPulse cron jobs started for sports, tournament templates, tournaments, tournament stages, fixtures, and results")
}