手动同步改为异步任务并前端轮询状态
This commit is contained in:
@@ -52,10 +52,31 @@ func (s *StockSyncService) SyncHistory(ctx context.Context, triggerBy string, mo
|
||||
})
|
||||
}
|
||||
|
||||
func (s *StockSyncService) runSyncJob(ctx context.Context, triggerBy string, fn func() (int, error)) (int, error) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
// StartSync 异步启动一次盘后同步,返回已创建的 job。
|
||||
func (s *StockSyncService) StartSync(ctx context.Context, triggerBy string) (*models.StockSyncJob, error) {
|
||||
job, err := s.createJob(ctx, triggerBy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go s.runSyncJobByID(context.Background(), job.ID, func(ctx context.Context) (int, error) {
|
||||
return s.doSync(ctx)
|
||||
})
|
||||
return job, nil
|
||||
}
|
||||
|
||||
// StartSyncHistory 异步启动近 N 个月历史同步,返回已创建的 job。
|
||||
func (s *StockSyncService) StartSyncHistory(ctx context.Context, triggerBy string, months int) (*models.StockSyncJob, error) {
|
||||
job, err := s.createJob(ctx, triggerBy)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go s.runSyncJobByID(context.Background(), job.ID, func(ctx context.Context) (int, error) {
|
||||
return s.doSyncHistory(ctx, months)
|
||||
})
|
||||
return job, nil
|
||||
}
|
||||
|
||||
func (s *StockSyncService) createJob(ctx context.Context, triggerBy string) (*models.StockSyncJob, error) {
|
||||
job := models.StockSyncJob{
|
||||
JobDate: today(),
|
||||
Status: "running",
|
||||
@@ -63,25 +84,46 @@ func (s *StockSyncService) runSyncJob(ctx context.Context, triggerBy string, fn
|
||||
TriggerBy: triggerBy,
|
||||
}
|
||||
if err := s.db.WithContext(ctx).Create(&job).Error; err != nil {
|
||||
return 0, fmt.Errorf("create sync job: %w", err)
|
||||
return nil, fmt.Errorf("create sync job: %w", err)
|
||||
}
|
||||
return &job, nil
|
||||
}
|
||||
|
||||
func (s *StockSyncService) runSyncJob(ctx context.Context, triggerBy string, fn func() (int, error)) (int, error) {
|
||||
job, err := s.createJob(ctx, triggerBy)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
recordsCount, err := fn()
|
||||
s.finishJob(ctx, job.ID, recordsCount, err)
|
||||
return recordsCount, err
|
||||
}
|
||||
|
||||
func (s *StockSyncService) runSyncJobByID(ctx context.Context, jobID string, fn func(context.Context) (int, error)) {
|
||||
s.mu.Lock()
|
||||
defer s.mu.Unlock()
|
||||
|
||||
recordsCount, err := fn(ctx)
|
||||
s.finishJob(ctx, jobID, recordsCount, err)
|
||||
}
|
||||
|
||||
func (s *StockSyncService) finishJob(ctx context.Context, jobID string, recordsCount int, jobErr error) {
|
||||
now := time.Now().UTC()
|
||||
updates := map[string]any{
|
||||
"records_count": recordsCount,
|
||||
"finished_at": &now,
|
||||
}
|
||||
if err != nil {
|
||||
if jobErr != nil {
|
||||
updates["status"] = "failed"
|
||||
updates["error_message"] = err.Error()
|
||||
updates["error_message"] = jobErr.Error()
|
||||
log.Printf("[stock sync] job %s failed: %v", jobID, jobErr)
|
||||
} else {
|
||||
updates["status"] = "success"
|
||||
log.Printf("[stock sync] job %s success, records=%d", jobID, recordsCount)
|
||||
}
|
||||
if err := s.db.WithContext(ctx).Model(&models.StockSyncJob{}).Where("id = ?", jobID).Updates(updates).Error; err != nil {
|
||||
log.Printf("[stock sync] update job %s failed: %v", jobID, err)
|
||||
}
|
||||
s.db.WithContext(ctx).Model(&job).Updates(updates)
|
||||
|
||||
return recordsCount, err
|
||||
}
|
||||
|
||||
func (s *StockSyncService) doSync(ctx context.Context) (int, error) {
|
||||
|
||||
Reference in New Issue
Block a user