Skip to Content
How-To GuidesGoScheduling a Future Agent Call from Go Code

Scheduling a Future Agent Call from Go Code

Overview

Method.Schedule(client, at, in) enqueues a one-off invocation of a method to run at a specific future time. It returns a *golem.ScheduledInvocation, whose Cancel() prevents the invocation if it has not started yet, and an error if the host refuses to schedule it; MustSchedule panics instead.

Like Trigger, Schedule does not wait for a result — so it is safe to target another agent or the same instance (a synchronous self-Call would deadlock). The scheduled time is recorded durably and survives restarts.

For a task that reschedules itself on an interval (a periodic / cron-like loop), see golem-recurring-task-go; this skill covers scheduling a single future call and canceling it.

Steps

  1. Get a client for the target instance: counter.Agent.Get(counter.ID{Name: "my-counter"}).
  2. Schedule the method at a time.Time: counter.Increment.MustSchedule(c, when, in).
  3. Keep the returned *golem.ScheduledInvocation if you may need to cancel it.
  4. Cancel with inv.Cancel() before the scheduled time to prevent it.

Scheduling a future call on another agent

package impl import ( "time" "myapp/agents/counter" "myapp/agents/scheduler" "github.com/golemcloud/golem/sdks/go/golem" ) type state struct{ pending *golem.ScheduledInvocation } var agent = scheduler.Agent.Implement(func(scheduler.ID) *state { return &state{} }) func init() { agent.Handle(scheduler.Arm, func(ctx *golem.Context[state], _ golem.Unit) golem.Unit { c := counter.Agent.Get(counter.ID{Name: "my-counter"}) // Run counter.increment 60 seconds from now. ctx.State.pending = counter.Increment.MustSchedule(c, time.Now().Add(60*time.Second), golem.Unit{}) return golem.Unit{} }) }

Schedule returns a *golem.ScheduledInvocation and an error; its ID field is the invocation’s InvocationID.

Scheduling a method that takes arguments

Pass the method’s input value as the last argument, exactly as with Call / Trigger:

c := counter.Agent.Get(counter.ID{Name: "my-counter"}) counter.Add.MustSchedule(c, time.Now().Add(24*time.Hour), counter.AddIn{By: 5})

Canceling a scheduled call

Keep the *golem.ScheduledInvocation (e.g. in state) and call Cancel():

func init() { agent.Handle(scheduler.Cancel, func(ctx *golem.Context[state], _ golem.Unit) golem.Unit { if ctx.State.pending != nil { ctx.State.pending.Cancel() // no-op if it has already started ctx.State.pending = nil } return golem.Unit{} }) }

Cancel() is idempotent: it does nothing if already canceled, and cannot un-run an invocation that has already started.

Scheduling a future call to itself

To message its own instance an agent binds a client to its own id (see golem-recurring-task-go for the full pattern):

self := golem.Must(counter.Agent.Bind(ctx.AgentID())) counter.Increment.MustSchedule(self, time.Now().Add(time.Minute), golem.Unit{})

Schedule vs Trigger

  • Schedule(c, at, in) (*ScheduledInvocation, error) — run once at a future time.Time; cancelable via Cancel(). MustSchedule panics on the error.
  • Trigger(c, in) (InvocationID, error) — enqueue immediately, no delay, not cancelable. Use it to advance to the next step now.
  • Never self-Call — a synchronous call into the same instance deadlocks; self-messaging must use Schedule or Trigger.

Key Constraints

  • Schedule / Trigger are called on the method descriptor (counter.Increment.Schedule(c, ...)), and the client comes from the callee’s definition (counter.Agent.Get(id)).
  • Compute the time with time.Now().Add(d) (a time.Time); it is recorded durably.
  • To cancel later, you must retain the *golem.ScheduledInvocation — don’t discard it if cancellation may be needed. Hold it in agent state, not across a bare var initializer.
  • For a self-scheduling recurring loop, don’t hand-roll it here — use golem-recurring-task-go.
GuideDescription
golem-recurring-task-goA self-rescheduling / periodic (cron-like) task
golem-fire-and-forget-goEnqueue an immediate invocation (Trigger)
golem-call-another-agent-goAwait a result from another agent (Call / CallAsync)
golem-schedule-agent-goSchedule a future invocation from the CLI