chore: 并入 iotlcm-worker-svr 历史到 worker-svr/(原提交 96f0f4e)
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
package batch
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
|
||||
"github.com/gogf/gf/v2/os/gtime"
|
||||
|
||||
"git.5iot.com/iotlcm-public/iotlcm-worker-svr/internal/model/entity"
|
||||
)
|
||||
|
||||
const (
|
||||
Type3 = 3
|
||||
Type4 = 4
|
||||
Type11 = 11
|
||||
Type12 = 12
|
||||
Type40 = 40
|
||||
Type41 = 41
|
||||
Type101 = 101
|
||||
Type102 = 102
|
||||
Type103 = 103
|
||||
Type104 = 104
|
||||
Type105 = 105
|
||||
Type106 = 106
|
||||
Type107 = 107
|
||||
Type108 = 108
|
||||
Type109 = 109
|
||||
Type110 = 110
|
||||
|
||||
AsyncStatusPending = 1
|
||||
AsyncStatusProcessing = 2
|
||||
AsyncStatusSuccess = 3
|
||||
AsyncStatusFailed = 4
|
||||
RunResultRunning = 1
|
||||
RunResultSuccess = 2
|
||||
RunResultFailed = 3
|
||||
|
||||
DetailStatusPending = 0
|
||||
DetailStatusRunning = 1
|
||||
DetailStatusSuccess = 2
|
||||
DetailStatusFailed = 3
|
||||
)
|
||||
|
||||
type Message struct {
|
||||
BatchNo string `json:"batchNo"`
|
||||
BatchType int `json:"batchType"`
|
||||
FailureReason string `json:"failureReason,omitempty"`
|
||||
Retryable bool `json:"retryable,omitempty"`
|
||||
}
|
||||
|
||||
// RetryableError marks an executor failure that may succeed after delayed redelivery.
|
||||
// The batch remains in processing until retries are exhausted and finalized.
|
||||
type RetryableError struct {
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *RetryableError) Error() string {
|
||||
if e == nil || e.Err == nil {
|
||||
return "retryable batch execution error"
|
||||
}
|
||||
return e.Err.Error()
|
||||
}
|
||||
|
||||
func (e *RetryableError) Unwrap() error {
|
||||
if e == nil {
|
||||
return nil
|
||||
}
|
||||
return e.Err
|
||||
}
|
||||
|
||||
func Retryable(err error) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if IsRetryable(err) {
|
||||
return err
|
||||
}
|
||||
return &RetryableError{Err: err}
|
||||
}
|
||||
|
||||
func IsRetryable(err error) bool {
|
||||
var retryableErr *RetryableError
|
||||
return errors.As(err, &retryableErr)
|
||||
}
|
||||
|
||||
// FailureMarkError 表示执行已结束,但失败终态尚未成功写入数据库。
|
||||
// 消费者重投这类消息时只能补写失败终态,不能再次执行具体业务。
|
||||
type FailureMarkError struct {
|
||||
Reason string
|
||||
Err error
|
||||
}
|
||||
|
||||
func (e *FailureMarkError) Error() string {
|
||||
return "mark batch failed after executor error: " + e.Reason + ": " + e.Err.Error()
|
||||
}
|
||||
|
||||
func (e *FailureMarkError) Unwrap() error {
|
||||
return e.Err
|
||||
}
|
||||
|
||||
type Executor interface {
|
||||
Execute(ctx context.Context, batchNo string) error
|
||||
}
|
||||
|
||||
type ProcessingExecutor interface {
|
||||
CanExecuteProcessing(ctx context.Context, main *entity.BatchMain) (bool, error)
|
||||
}
|
||||
|
||||
// SelfClaimingProcessingExecutor marks executors that perform their own
|
||||
// processing-state CAS before executing a re-entry phase.
|
||||
type SelfClaimingProcessingExecutor interface {
|
||||
ClaimsProcessingReentry() bool
|
||||
}
|
||||
|
||||
// DurableFailureHandler takes ownership before any generic MarkFailed fallback.
|
||||
type DurableFailureHandler interface {
|
||||
ProtectExecutionFailure(ctx context.Context, batchNo string, batchType int, reason string) (bool, error)
|
||||
}
|
||||
|
||||
type ExecutionFailureHandler interface {
|
||||
HandleExecutionFailure(ctx context.Context, batchNo string, batchType int, reason string) error
|
||||
}
|
||||
|
||||
type ProcessingClaimer interface {
|
||||
ReclaimProcessing(ctx context.Context, batchNo string, batchType int, startedAt *gtime.Time) (bool, error)
|
||||
}
|
||||
|
||||
type Dispatcher struct {
|
||||
executors map[int]Executor
|
||||
}
|
||||
|
||||
func NewDispatcher(executor Executor) *Dispatcher {
|
||||
return &Dispatcher{executors: map[int]Executor{
|
||||
Type103: executor,
|
||||
Type104: executor,
|
||||
}}
|
||||
}
|
||||
|
||||
func (d *Dispatcher) Register(batchType int, executor Executor) {
|
||||
if d == nil || executor == nil {
|
||||
return
|
||||
}
|
||||
d.executors[batchType] = executor
|
||||
}
|
||||
|
||||
func (d *Dispatcher) Executor(batchType int) (Executor, bool) {
|
||||
if d == nil {
|
||||
return nil, false
|
||||
}
|
||||
executor, ok := d.executors[batchType]
|
||||
return executor, ok && executor != nil
|
||||
}
|
||||
|
||||
func (d *Dispatcher) Has(batchType int) bool {
|
||||
_, ok := d.Executor(batchType)
|
||||
return ok
|
||||
}
|
||||
Reference in New Issue
Block a user