Add TED Scraper Configuration and Cron Scheduler Implementation
- Introduced a new configuration file for the TED scraper, defining database connection settings, logging preferences, and scraping parameters. - Implemented a CronScheduler to manage scheduled tasks for TED operations, utilizing the robfig/cron library for scheduling. - Added new entities and structures for handling TED XML data, including eForms and tender-related information, enhancing the scraper's functionality. - Updated the main application to initialize the TED scraper with the new configuration and set up graceful shutdown handling. - Removed the deprecated scraping implementation to streamline the codebase and focus on the new architecture.
This commit is contained in:
@@ -0,0 +1,144 @@
|
||||
package schedule
|
||||
|
||||
import (
|
||||
"time"
|
||||
"tm/internal/tender"
|
||||
"tm/pkg/logger"
|
||||
"tm/pkg/mongo"
|
||||
|
||||
"github.com/robfig/cron/v3"
|
||||
)
|
||||
|
||||
// CronScheduler handles scheduled tasks for TED operations
|
||||
type CronScheduler struct {
|
||||
cron *cron.Cron
|
||||
mongoManager *mongo.ConnectionManager
|
||||
tenderRepo tender.TenderRepository
|
||||
logger logger.Logger
|
||||
}
|
||||
|
||||
// Logger interface for structured logging
|
||||
type Logger interface {
|
||||
Info(msg string, fields map[string]interface{})
|
||||
Error(msg string, fields map[string]interface{})
|
||||
Debug(msg string, fields map[string]interface{})
|
||||
}
|
||||
|
||||
type Job struct {
|
||||
Name string
|
||||
Func func()
|
||||
Expr string
|
||||
}
|
||||
|
||||
// NewCronScheduler creates a new cron scheduler instance
|
||||
func NewCronScheduler(logger logger.Logger, mongoManager *mongo.ConnectionManager, tenderRepo tender.TenderRepository) *CronScheduler {
|
||||
// Create cron with timezone support and seconds precision
|
||||
c := cron.New(cron.WithLocation(time.UTC), cron.WithSeconds())
|
||||
|
||||
return &CronScheduler{
|
||||
cron: c,
|
||||
mongoManager: mongoManager,
|
||||
tenderRepo: tenderRepo,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
// Start starts the cron scheduler
|
||||
func (cs *CronScheduler) Start() {
|
||||
cs.logger.Info("Starting TED cron scheduler", map[string]interface{}{})
|
||||
cs.cron.Start()
|
||||
}
|
||||
|
||||
// Stop stops the cron scheduler gracefully
|
||||
func (cs *CronScheduler) Stop() {
|
||||
cs.logger.Info("Stopping TED cron scheduler", map[string]interface{}{})
|
||||
ctx := cs.cron.Stop()
|
||||
<-ctx.Done()
|
||||
}
|
||||
|
||||
// ScheduleDailyJob schedules a job to run daily at 10:00 AM UTC
|
||||
func (cs *CronScheduler) AddJob(job Job) error {
|
||||
// Cron expression: "0 0 10 * * *" means:
|
||||
// Second: 0
|
||||
// Minute: 0
|
||||
// Hour: 10 (10 AM)
|
||||
// Day of month: * (every day)
|
||||
// Month: * (every month)
|
||||
// Day of week: * (every day of week)
|
||||
_, err := cs.cron.AddFunc(job.Expr, func() {
|
||||
now := time.Now().Local()
|
||||
cs.logger.Info("Starting daily TED job", map[string]interface{}{
|
||||
"job_name": job.Name,
|
||||
"cron_expression": job.Expr,
|
||||
"time": time.Now().Format(time.RFC3339),
|
||||
})
|
||||
|
||||
job.Func()
|
||||
|
||||
cs.logger.Info("Completed job successfully", map[string]interface{}{
|
||||
"time": now.Format(time.RFC3339),
|
||||
"job_name": job.Name,
|
||||
"cron_expression": job.Expr,
|
||||
})
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
cs.logger.Error("Failed to schedule daily job", map[string]interface{}{
|
||||
"error": err.Error(),
|
||||
"job_name": job.Name,
|
||||
"cron_expression": job.Expr,
|
||||
"time": time.Now().Format(time.RFC3339),
|
||||
})
|
||||
return err
|
||||
}
|
||||
|
||||
cs.logger.Info("Daily job scheduled successfully", map[string]interface{}{
|
||||
"job_name": job.Name,
|
||||
"cron_expression": job.Expr,
|
||||
"time": time.Now().Format(time.RFC3339),
|
||||
})
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ExampleTEDScrapingJob is an example job function that can be scheduled
|
||||
func ExampleTEDScrapingJob() {
|
||||
// now := time.Now().Local()
|
||||
// // Example: Get current date for TED scraping
|
||||
// currentDate := time.Now().Format("02/01/2006")
|
||||
// currentYear := time.Now().Year()
|
||||
|
||||
// // This is just an example - replace with actual TED scraping logic
|
||||
// ojs, err := GetOJS(currentYear, currentDate)
|
||||
// if err != nil {
|
||||
// log.Printf("Error getting OJS: %v", err)
|
||||
// return
|
||||
// }
|
||||
|
||||
// log.Printf("Successfully retrieved OJS: %s for date: %s", ojs, currentDate)
|
||||
|
||||
// Add your actual TED scraping/processing logic here
|
||||
|
||||
// ojs, err := GetOJS(now.Year(), now.Format("02/01/2006"))
|
||||
// if err != nil {
|
||||
// cs.logger.Error("Failed to get OJS", map[string]interface{}{
|
||||
// "error": err.Error(),
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
// scraper := NewTEDScraper(cs.config, cs.logger, cs.mongoManager, cs.tenderRepo)
|
||||
// result, err := scraper.DownloadDailyPackage(context.Background(), ojs)
|
||||
// if err != nil {
|
||||
// cs.logger.Error("Failed to download daily package", map[string]interface{}{
|
||||
// "error": err.Error(),
|
||||
// })
|
||||
// return
|
||||
// }
|
||||
|
||||
// cs.logger.Info("Downloaded daily package successfully", map[string]interface{}{
|
||||
// "result": result,
|
||||
// "time": now.Format(time.RFC3339),
|
||||
// "ojs": ojs,
|
||||
// })
|
||||
}
|
||||
Reference in New Issue
Block a user