package grpc import ( "context" "time" activityv1 "hyapp.local/api/proto/activity/v1" "hyapp/pkg/appcode" "hyapp/pkg/xerr" messageservice "hyapp/services/activity-service/internal/service/message" ) // CronServer exposes activity-service owned background batches to cron-service. type CronServer struct { activityv1.UnimplementedActivityCronServiceServer message *messageservice.Service } // NewCronServer creates the internal cron adapter without exposing message storage. func NewCronServer(messageSvc *messageservice.Service) *CronServer { return &CronServer{message: messageSvc} } // ProcessMessageFanoutBatch claims and processes one message fanout page. func (s *CronServer) ProcessMessageFanoutBatch(ctx context.Context, req *activityv1.CronBatchRequest) (*activityv1.CronBatchResponse, error) { ctx = appcode.WithContext(ctx, req.GetMeta().GetAppCode()) if s.message == nil { return nil, xerr.ToGRPCError(xerr.New(xerr.Unavailable, "message service is not configured")) } processed, err := s.message.ProcessNextFanoutJob(ctx, messageservice.FanoutWorkerOptions{ WorkerID: req.GetWorkerId(), BatchSize: int(req.GetBatchSize()), LockTTL: durationFromMillis(req.GetLockTtlMs()), }) if err != nil { return nil, xerr.ToGRPCError(err) } if !processed { return &activityv1.CronBatchResponse{}, nil } return &activityv1.CronBatchResponse{ ClaimedCount: 1, ProcessedCount: 1, SuccessCount: 1, HasMore: true, }, nil } func durationFromMillis(value int64) time.Duration { if value <= 0 { return 0 } return time.Duration(value) * time.Millisecond }