mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-08 00:26:37 +08:00
feat(core): bind request services and implement registered tasks
Wire plugin services through Bind/InjectFrom and AppContext so HTTP and workers resolve dependencies after Apply. Register TaskHandler objects with persisted results, and implement send_email_code, mail:send, cleanup_inactive_users, and dispatch_bot_msg.
This commit is contained in:
@@ -75,7 +75,7 @@ func IsAllowedLogOrigin(ctx context.Context, origin, host string) bool {
|
||||
|
||||
// AccessLogs queries the analytical access log store and decorates rows with user names.
|
||||
func AccessLogs(ctx context.Context, q model.AccessLogQuery) (model.AccessLogsResponse, error) {
|
||||
rc := GetRiskControlService()
|
||||
rc := GetRiskControlService(ctx)
|
||||
if rc == nil {
|
||||
return model.AccessLogsResponse{}, errs.ErrLogStoreUnavailable
|
||||
}
|
||||
@@ -117,7 +117,7 @@ func AccessLogs(ctx context.Context, q model.AccessLogQuery) (model.AccessLogsRe
|
||||
|
||||
// AccessLogAnalytics aggregates the daily trend of the access log store.
|
||||
func AccessLogAnalytics(ctx context.Context) (model.LogsAnalyticsResponse, error) {
|
||||
rc := GetRiskControlService()
|
||||
rc := GetRiskControlService(ctx)
|
||||
if rc == nil {
|
||||
return model.LogsAnalyticsResponse{}, errs.ErrLogStoreUnavailable
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ func (h *LogDBSwitchHandler) Execute(ctx context.Context, payload []byte) (*cont
|
||||
return nil, err
|
||||
}
|
||||
|
||||
taskSvc := GetTaskService()
|
||||
taskSvc := GetTaskService(ctx)
|
||||
if taskSvc != nil {
|
||||
taskSvc.AppendLog(ctx, "开始切换日志数据库:%s -> %s", source, p.Target)
|
||||
}
|
||||
@@ -123,7 +123,7 @@ func (h *LogDBSwitchHandler) Execute(ctx context.Context, payload []byte) (*cont
|
||||
}
|
||||
}()
|
||||
|
||||
rc := GetRiskControlService()
|
||||
rc := GetRiskControlService(ctx)
|
||||
if rc != nil {
|
||||
if err := rc.SwitchLogEngine(ctx, p.Target); err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"Wavelet/core"
|
||||
"Wavelet/core/contracts"
|
||||
"Wavelet/plugins/domain/admin/errs"
|
||||
"Wavelet/plugins/domain/admin/repository"
|
||||
@@ -112,6 +113,9 @@ func ResetServices() {
|
||||
|
||||
// GetDB returns the GORM DB instance bound to the context if available.
|
||||
func GetDB(ctx context.Context) *gorm.DB {
|
||||
if s, err := core.InjectFrom[contracts.DBService](ctx); err == nil && s != nil {
|
||||
return s.DB(ctx)
|
||||
}
|
||||
servicesMu.RLock()
|
||||
defer servicesMu.RUnlock()
|
||||
if dbService == nil {
|
||||
@@ -121,42 +125,60 @@ func GetDB(ctx context.Context) *gorm.DB {
|
||||
}
|
||||
|
||||
// GetCache returns the unified CacheService instance.
|
||||
func GetCache(_ context.Context) contracts.CacheService {
|
||||
func GetCache(ctx context.Context) contracts.CacheService {
|
||||
if s, err := core.InjectFrom[contracts.CacheService](ctx); err == nil && s != nil {
|
||||
return s
|
||||
}
|
||||
servicesMu.RLock()
|
||||
defer servicesMu.RUnlock()
|
||||
return cacheService
|
||||
}
|
||||
|
||||
// GetUserService returns the UserService instance.
|
||||
func GetUserService(_ context.Context) contracts.UserService {
|
||||
func GetUserService(ctx context.Context) contracts.UserService {
|
||||
if s, err := core.InjectFrom[contracts.UserService](ctx); err == nil && s != nil {
|
||||
return s
|
||||
}
|
||||
servicesMu.RLock()
|
||||
defer servicesMu.RUnlock()
|
||||
return userService
|
||||
}
|
||||
|
||||
// GetAuthService returns the AuthService instance.
|
||||
func GetAuthService(_ context.Context) contracts.AuthService {
|
||||
func GetAuthService(ctx context.Context) contracts.AuthService {
|
||||
if s, err := core.InjectFrom[contracts.AuthService](ctx); err == nil && s != nil {
|
||||
return s
|
||||
}
|
||||
servicesMu.RLock()
|
||||
defer servicesMu.RUnlock()
|
||||
return authService
|
||||
}
|
||||
|
||||
// GetTaskService returns the TaskService instance.
|
||||
func GetTaskService() contracts.TaskService {
|
||||
func GetTaskService(ctx context.Context) contracts.TaskService {
|
||||
if s, err := core.InjectFrom[contracts.TaskService](ctx); err == nil && s != nil {
|
||||
return s
|
||||
}
|
||||
servicesMu.RLock()
|
||||
defer servicesMu.RUnlock()
|
||||
return taskService
|
||||
}
|
||||
|
||||
// GetStorageService returns the StorageService instance.
|
||||
func GetStorageService() contracts.StorageService {
|
||||
func GetStorageService(ctx context.Context) contracts.StorageService {
|
||||
if s, err := core.InjectFrom[contracts.StorageService](ctx); err == nil && s != nil {
|
||||
return s
|
||||
}
|
||||
servicesMu.RLock()
|
||||
defer servicesMu.RUnlock()
|
||||
return storageSvc
|
||||
}
|
||||
|
||||
// GetRiskControlService returns the RiskControlService instance.
|
||||
func GetRiskControlService() contracts.RiskControlService {
|
||||
func GetRiskControlService(ctx context.Context) contracts.RiskControlService {
|
||||
if s, err := core.InjectFrom[contracts.RiskControlService](ctx); err == nil && s != nil {
|
||||
return s
|
||||
}
|
||||
servicesMu.RLock()
|
||||
defer servicesMu.RUnlock()
|
||||
return riskControlService
|
||||
@@ -195,8 +217,8 @@ func requireAuthService(ctx context.Context) (contracts.AuthService, error) {
|
||||
}
|
||||
|
||||
// requireTaskService resolves the injected task contract service.
|
||||
func requireTaskService() (contracts.TaskService, error) {
|
||||
taskSvc := GetTaskService()
|
||||
func requireTaskService(ctx context.Context) (contracts.TaskService, error) {
|
||||
taskSvc := GetTaskService(ctx)
|
||||
if taskSvc == nil {
|
||||
return nil, errs.ErrTaskServiceUnavailable
|
||||
}
|
||||
|
||||
@@ -117,7 +117,7 @@ func formatDuration(d time.Duration) string {
|
||||
func LogDatabaseStatus(ctx context.Context) model.LogDatabaseStatus {
|
||||
activeDB := logDBNameSQLite
|
||||
migration := logMigrationIdle
|
||||
if rc := GetRiskControlService(); rc != nil {
|
||||
if rc := GetRiskControlService(ctx); rc != nil {
|
||||
activeDB = rc.ActiveLogEngine(ctx)
|
||||
if rc.IsLogEngineMigrating(ctx) {
|
||||
migration = logMigrationInProgress
|
||||
|
||||
@@ -17,8 +17,8 @@ import (
|
||||
)
|
||||
|
||||
// ListTaskTypes returns every dispatchable task type declared in the task registry.
|
||||
func ListTaskTypes() []contracts.TaskMetaDTO {
|
||||
taskSvc := GetTaskService()
|
||||
func ListTaskTypes(ctx context.Context) []contracts.TaskMetaDTO {
|
||||
taskSvc := GetTaskService(ctx)
|
||||
if taskSvc == nil {
|
||||
return []contracts.TaskMetaDTO{}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ func ListTaskTypes() []contracts.TaskMetaDTO {
|
||||
|
||||
// DispatchTask validates and enqueues a manual task run, returning the new task id.
|
||||
func DispatchTask(ctx context.Context, req model.DispatchTaskRequest) (string, error) {
|
||||
taskSvc, err := requireTaskService()
|
||||
taskSvc, err := requireTaskService(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -67,29 +67,75 @@ func ListTaskExecutions(
|
||||
ctx context.Context,
|
||||
req model.ListTaskExecutionsRequest,
|
||||
) ([]model.TaskExecution, int64, error) {
|
||||
if req.TaskType != "" {
|
||||
if taskSvc := GetTaskService(); taskSvc != nil {
|
||||
if meta, ok := taskSvc.GetTaskMeta(req.TaskType); ok {
|
||||
req.TaskType = meta.Name
|
||||
}
|
||||
taskSvc, err := requireTaskService(ctx)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
if req.Page <= 0 {
|
||||
req.Page = 1
|
||||
}
|
||||
if req.PageSize <= 0 {
|
||||
req.PageSize = 20
|
||||
}
|
||||
|
||||
filterType := req.TaskType
|
||||
if filterType != "" {
|
||||
if meta, ok := taskSvc.GetTaskMeta(filterType); ok {
|
||||
filterType = meta.AsynqTask
|
||||
}
|
||||
}
|
||||
|
||||
executions, total, err := repository.ListTaskExecutionRecords(ctx, req)
|
||||
rows, total, err := taskSvc.ListExecutions(ctx, filterType, req.Status, req.Page, req.PageSize)
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
executions := make([]model.TaskExecution, 0, len(rows))
|
||||
for i := range rows {
|
||||
executions = append(executions, executionFromDTO(rows[i]))
|
||||
}
|
||||
return executions, total, nil
|
||||
}
|
||||
|
||||
// TaskExecution loads a single execution record including its buffered log.
|
||||
func TaskExecution(ctx context.Context, id uint64) (*model.TaskExecution, error) {
|
||||
return repository.GetTaskExecutionByID(ctx, id)
|
||||
taskSvc, err := requireTaskService(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dto, err := taskSvc.GetExecution(ctx, id)
|
||||
if err != nil || dto == nil {
|
||||
return nil, err
|
||||
}
|
||||
row := executionFromDTO(*dto)
|
||||
return &row, nil
|
||||
}
|
||||
|
||||
func executionFromDTO(dto contracts.TaskExecutionDTO) model.TaskExecution {
|
||||
return model.TaskExecution{
|
||||
ID: dto.ID,
|
||||
TaskID: dto.TaskID,
|
||||
TaskType: dto.TaskType,
|
||||
TaskName: dto.TaskName,
|
||||
Status: model.TaskExecutionStatus(dto.Status),
|
||||
Retryable: dto.Retryable,
|
||||
MaxRetry: dto.MaxRetry,
|
||||
RetryCount: dto.RetryCount,
|
||||
Log: dto.Log,
|
||||
ErrorMessage: dto.ErrorMessage,
|
||||
Result: dto.Result,
|
||||
StartedAt: dto.StartedAt,
|
||||
FinishedAt: dto.FinishedAt,
|
||||
Duration: dto.Duration,
|
||||
Payload: dto.Payload,
|
||||
TriggeredBy: dto.TriggeredBy,
|
||||
CreatedAt: dto.CreatedAt,
|
||||
UpdatedAt: dto.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
// RetryTask re-dispatches a failed execution as a new task run.
|
||||
func RetryTask(ctx context.Context, id uint64) (string, error) {
|
||||
taskSvc, err := requireTaskService()
|
||||
taskSvc, err := requireTaskService(ctx)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -126,7 +172,7 @@ func CreateSchedule(ctx context.Context, req model.CreateScheduleRequest) (*mode
|
||||
return nil, errs.ErrInvalidCronExpression
|
||||
}
|
||||
|
||||
taskSvc, err := requireTaskService()
|
||||
taskSvc, err := requireTaskService(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -168,7 +214,7 @@ func UpdateSchedule(ctx context.Context, id uint64, req model.UpdateScheduleRequ
|
||||
return nil, errs.ErrInvalidCronExpression
|
||||
}
|
||||
|
||||
taskSvc, err := requireTaskService()
|
||||
taskSvc, err := requireTaskService(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -203,7 +249,7 @@ func DeleteSchedule(ctx context.Context, id uint64) error {
|
||||
return fmt.Errorf("%s: %w", errs.ScheduleDeleteFailed, err)
|
||||
}
|
||||
|
||||
if taskSvc := GetTaskService(); taskSvc != nil {
|
||||
if taskSvc := GetTaskService(ctx); taskSvc != nil {
|
||||
reloadScheduler(ctx, taskSvc)
|
||||
}
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user