197 lines
6.1 KiB
Go
197 lines
6.1 KiB
Go
package fedwiki
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"time"
|
|
|
|
"git.coopcloud.tech/wiki-cafe/member-console/internal/workflows/queues"
|
|
"go.temporal.io/sdk/client"
|
|
)
|
|
|
|
const (
|
|
// SyncScheduleID is the unique identifier for the FedWiki site sync schedule.
|
|
SyncScheduleID = "fedwiki-site-sync"
|
|
// SyncWorkflowID is the workflow ID used for sync workflow executions.
|
|
SyncWorkflowID = "fedwiki-site-sync-workflow"
|
|
// DefaultSyncInterval is the default interval between site syncs.
|
|
DefaultSyncInterval = 1 * time.Hour
|
|
)
|
|
|
|
// ScheduleConfig holds configuration for the FedWiki sync schedule.
|
|
type ScheduleConfig struct {
|
|
// Interval is how often to run the sync workflow.
|
|
Interval time.Duration
|
|
// DefaultUserID is the user ID to assign to orphaned sites.
|
|
DefaultUserID int64
|
|
// TriggerImmediately runs the sync immediately when creating the schedule.
|
|
TriggerImmediately bool
|
|
}
|
|
|
|
// DefaultScheduleConfig returns a default schedule configuration.
|
|
func DefaultScheduleConfig() ScheduleConfig {
|
|
return ScheduleConfig{
|
|
Interval: DefaultSyncInterval,
|
|
DefaultUserID: 1, // Typically the admin/system user
|
|
TriggerImmediately: true,
|
|
}
|
|
}
|
|
|
|
// ScheduleManager manages Temporal schedules for FedWiki operations.
|
|
type ScheduleManager struct {
|
|
client client.Client
|
|
logger *slog.Logger
|
|
}
|
|
|
|
// NewScheduleManager creates a new ScheduleManager.
|
|
func NewScheduleManager(c client.Client, logger *slog.Logger) *ScheduleManager {
|
|
return &ScheduleManager{
|
|
client: c,
|
|
logger: logger,
|
|
}
|
|
}
|
|
|
|
// EnsureSyncSchedule creates or updates the FedWiki site sync schedule.
|
|
// If the schedule already exists, it updates the schedule's spec.
|
|
// If it doesn't exist, it creates a new schedule.
|
|
func (m *ScheduleManager) EnsureSyncSchedule(ctx context.Context, cfg ScheduleConfig) error {
|
|
if cfg.Interval == 0 {
|
|
cfg.Interval = DefaultSyncInterval
|
|
}
|
|
|
|
scheduleClient := m.client.ScheduleClient()
|
|
|
|
// Try to get the existing schedule
|
|
handle := scheduleClient.GetHandle(ctx, SyncScheduleID)
|
|
_, err := handle.Describe(ctx)
|
|
if err == nil {
|
|
// Schedule exists, update it
|
|
m.logger.Info("updating existing FedWiki sync schedule",
|
|
slog.Duration("interval", cfg.Interval))
|
|
|
|
err = handle.Update(ctx, client.ScheduleUpdateOptions{
|
|
DoUpdate: func(schedule client.ScheduleUpdateInput) (*client.ScheduleUpdate, error) {
|
|
schedule.Description.Schedule.Spec = &client.ScheduleSpec{
|
|
Intervals: []client.ScheduleIntervalSpec{
|
|
{Every: cfg.Interval},
|
|
},
|
|
}
|
|
schedule.Description.Schedule.Action = &client.ScheduleWorkflowAction{
|
|
ID: SyncWorkflowID,
|
|
Workflow: SyncFedWikiSitesWorkflow,
|
|
TaskQueue: queues.Main,
|
|
Args: []interface{}{
|
|
SyncFedWikiSitesWorkflowInput{
|
|
DefaultUserID: cfg.DefaultUserID,
|
|
},
|
|
},
|
|
}
|
|
return &client.ScheduleUpdate{
|
|
Schedule: &schedule.Description.Schedule,
|
|
}, nil
|
|
},
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to update sync schedule: %w", err)
|
|
}
|
|
|
|
m.logger.Info("FedWiki sync schedule updated successfully")
|
|
return nil
|
|
}
|
|
|
|
// Schedule doesn't exist, create it
|
|
m.logger.Info("creating FedWiki sync schedule",
|
|
slog.Duration("interval", cfg.Interval),
|
|
slog.Bool("triggerImmediately", cfg.TriggerImmediately))
|
|
|
|
_, err = scheduleClient.Create(ctx, client.ScheduleOptions{
|
|
ID: SyncScheduleID,
|
|
Spec: client.ScheduleSpec{
|
|
Intervals: []client.ScheduleIntervalSpec{
|
|
{Every: cfg.Interval},
|
|
},
|
|
},
|
|
Action: &client.ScheduleWorkflowAction{
|
|
ID: SyncWorkflowID,
|
|
Workflow: SyncFedWikiSitesWorkflow,
|
|
TaskQueue: queues.Main,
|
|
Args: []interface{}{
|
|
SyncFedWikiSitesWorkflowInput{
|
|
DefaultUserID: cfg.DefaultUserID,
|
|
},
|
|
},
|
|
},
|
|
TriggerImmediately: cfg.TriggerImmediately,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create sync schedule: %w", err)
|
|
}
|
|
|
|
m.logger.Info("FedWiki sync schedule created successfully",
|
|
slog.String("scheduleID", SyncScheduleID))
|
|
return nil
|
|
}
|
|
|
|
// DeleteSyncSchedule deletes the FedWiki site sync schedule.
|
|
func (m *ScheduleManager) DeleteSyncSchedule(ctx context.Context) error {
|
|
handle := m.client.ScheduleClient().GetHandle(ctx, SyncScheduleID)
|
|
err := handle.Delete(ctx)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to delete sync schedule: %w", err)
|
|
}
|
|
m.logger.Info("FedWiki sync schedule deleted", slog.String("scheduleID", SyncScheduleID))
|
|
return nil
|
|
}
|
|
|
|
// PauseSyncSchedule pauses the FedWiki site sync schedule.
|
|
func (m *ScheduleManager) PauseSyncSchedule(ctx context.Context, note string) error {
|
|
handle := m.client.ScheduleClient().GetHandle(ctx, SyncScheduleID)
|
|
err := handle.Pause(ctx, client.SchedulePauseOptions{
|
|
Note: note,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to pause sync schedule: %w", err)
|
|
}
|
|
m.logger.Info("FedWiki sync schedule paused",
|
|
slog.String("scheduleID", SyncScheduleID),
|
|
slog.String("note", note))
|
|
return nil
|
|
}
|
|
|
|
// UnpauseSyncSchedule unpauses (resumes) the FedWiki site sync schedule.
|
|
func (m *ScheduleManager) UnpauseSyncSchedule(ctx context.Context, note string) error {
|
|
handle := m.client.ScheduleClient().GetHandle(ctx, SyncScheduleID)
|
|
err := handle.Unpause(ctx, client.ScheduleUnpauseOptions{
|
|
Note: note,
|
|
})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to unpause sync schedule: %w", err)
|
|
}
|
|
m.logger.Info("FedWiki sync schedule unpaused",
|
|
slog.String("scheduleID", SyncScheduleID),
|
|
slog.String("note", note))
|
|
return nil
|
|
}
|
|
|
|
// TriggerSyncNow triggers an immediate execution of the sync workflow.
|
|
func (m *ScheduleManager) TriggerSyncNow(ctx context.Context) error {
|
|
handle := m.client.ScheduleClient().GetHandle(ctx, SyncScheduleID)
|
|
err := handle.Trigger(ctx, client.ScheduleTriggerOptions{})
|
|
if err != nil {
|
|
return fmt.Errorf("failed to trigger sync schedule: %w", err)
|
|
}
|
|
m.logger.Info("FedWiki sync triggered", slog.String("scheduleID", SyncScheduleID))
|
|
return nil
|
|
}
|
|
|
|
// GetSyncScheduleInfo returns information about the sync schedule.
|
|
func (m *ScheduleManager) GetSyncScheduleInfo(ctx context.Context) (*client.ScheduleDescription, error) {
|
|
handle := m.client.ScheduleClient().GetHandle(ctx, SyncScheduleID)
|
|
desc, err := handle.Describe(ctx)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("failed to describe sync schedule: %w", err)
|
|
}
|
|
return desc, nil
|
|
}
|