func (c *InternalCron) ScheduleEvent(ctx *core.Context, se *ScheduledEvent) error { sched, _, err := ParseSchedule(se.Schedule) if err != nil { return err } var event core.Map if err = json.Unmarshal([]byte(se.Event), &event); err != nil { return err } fn := func(t time.Time) error { loc := ctx.Location() if loc == nil { return errors.New("no location in ctx") } fr, err := loc.ProcessEvent(ctx, event) if err != nil { return err } core.Log(core.DEBUG|CRON, ctx, "InternalCron.ScheduleEvent", "findrules", *fr) return nil } return c.Cron.Add(ctx, se.Id, sched, fn) }
func AddHooks(ctx *core.Context, cronner Cronner, state core.State) error { add := func(ctx *core.Context, state core.State, id string, fact core.Map, loading bool) error { if cronner.Persistent() && loading { return nil } schedule, err := getSchedule(ctx, fact) if err != nil { return err } if schedule == "" { return nil } if cronner == nil { return errors.New("no cron available") } location := ctx.Location().Name core.Log(core.INFO|CRON, ctx, "addHook", "id", id, "location", location, "schedule", schedule) event := fmt.Sprintf(`{"trigger!":"%s"}`, id) se := &ScheduledEvent{ Id: id, Event: event, Schedule: schedule, } if err = cronner.ScheduleEvent(ctx, se); err != nil { core.Log(core.WARN|CRON, ctx, "addHook", "id", id, "error", err) return err } return nil } state.AddHook(add) rem := func(ctx *core.Context, state core.State, id string) error { core.Log(core.INFO|CRON, ctx, "remHook", "id", id) // Sad that we have to get the whole fact. // Yikes! The caller of this hook already has the state lock! fact, err := state.Get(ctx, id) if err != nil { return err } if fact == nil { core.Log(core.WARN|CRON, ctx, "remHook", "missing", id) return nil } schedule, err := getSchedule(ctx, fact) if err != nil { return err } if schedule == "" { return nil } if cronner == nil { return errors.New("no cron available") } _, err = cronner.Rem(ctx, id) return err } state.RemHook(rem) return nil }