Created
November 24, 2023 03:14
-
-
Save alsritter/e1456a1bad93e3c420dd12648f7860ae to your computer and use it in GitHub Desktop.
cron-service.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package cron | |
import ( | |
"context" | |
"fmt" | |
"github.com/go-kratos/kratos/v2/log" | |
"github.com/robfig/cron/v3" | |
"go.opentelemetry.io/otel/attribute" | |
"go.opentelemetry.io/otel/trace" | |
) | |
type ServerOption = func(opts *Server) | |
func WithTracer(v trace.Tracer) ServerOption { | |
return func(opts *Server) { | |
opts.tracer = v | |
} | |
} | |
func WithLogger(v *log.Helper) ServerOption { | |
return func(opts *Server) { | |
opts.log = v | |
} | |
} | |
type Server struct { | |
tracer trace.Tracer | |
log *log.Helper | |
cron *cron.Cron | |
} | |
func NewServer(options ...ServerOption) *Server { | |
srv := &Server{ | |
cron: cron.New(), | |
log: log.NewHelper(log.DefaultLogger), | |
} | |
for _, option := range options { | |
option(srv) | |
} | |
return srv | |
} | |
func (s *Server) Start(ctx context.Context) error { | |
s.cron.Start() | |
<-ctx.Done() | |
s.cron.Stop() | |
return ctx.Err() | |
} | |
func (s *Server) Stop(ctx context.Context) error { | |
s.cron.Stop() | |
return nil | |
} | |
func (s *Server) AddTask(schedule string, job func(ctx context.Context) error) error { | |
_, err := s.cron.AddFunc(schedule, s.wrapFunc(job)) | |
if err != nil { | |
return fmt.Errorf("failed to add task: %v", err) | |
} | |
return nil | |
} | |
// 包装异常处理的函数 | |
func (s *Server) wrapFunc(f func(ctx context.Context) error) func() { | |
return func() { | |
ctx := context.Background() | |
var ( | |
span trace.Span | |
err error | |
) | |
if s.tracer != nil { | |
kind := trace.SpanKindConsumer | |
ctx, span = s.tracer.Start(ctx, "cron-server", trace.WithSpanKind(kind)) | |
defer func() { | |
if err != nil { | |
span.RecordError(err) | |
} | |
span.End() | |
}() | |
} | |
defer func() { | |
if r := recover(); r != nil { | |
s.log.WithContext(ctx).Errorf("cron panic: %v", r) | |
if span != nil { | |
span.SetAttributes(attribute.Bool("error", true)) | |
span.RecordError(r.(error)) | |
} | |
err = r.(error) | |
} | |
}() | |
err = f(ctx) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment