Skip to content

Commit 8fd9d91

Browse files
authored
Add more detail to how workflow.Now behaves (#1228)
Docs are currently a bit vague on what time exactly it represents, which brings up questions like "is this the same as the cron schedule start time" or "what time does it represent if my workers are down for an hour". So this description was gathered experimentally. It may be a good idea to track exactly what updates it and when, but I suspect that the "recorded event" is a complete description. Or it probably should be.
1 parent 23fec5c commit 8fd9d91

File tree

1 file changed

+23
-2
lines changed

1 file changed

+23
-2
lines changed

workflow/deterministic_wrappers.go

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,29 @@ func NewFuture(ctx Context) (Future, Settable) {
117117
return internal.NewFuture(ctx)
118118
}
119119

120-
// Now returns the current time when the decision is started or replayed.
121-
// The workflow needs to use this Now() to get the wall clock time instead of the Go lang library one.
120+
// Now returns the time that the current decision task was started.
121+
// Workflows need to base any behavior off this time, rather than `time.Now()`, because `time.Now()` will change during
122+
// future replays.
123+
//
124+
// Because it is based on the decision task start time (not the scheduled time), this means it is nearly identical to
125+
// `time.Now()`, with roughly only RPC delay difference, clock skew, etc.
126+
// However, because it is stable during a decision task, operations like this will not work like a normal `time.Time`:
127+
//
128+
// before := workflow.Now(ctx)
129+
// somethingComputationallyExpensive() // no activities, i.e. non-blocking, takes 1 second to compute
130+
// after := workflow.Now(ctx)
131+
// elapsed := after.Sub(before) // this will be 0
132+
//
133+
// It will however show the elapsed time spent waiting for an activity and any decision task delays, because there will
134+
// be a new decision task for the second `workflow.Now(ctx)` call:
135+
//
136+
// before := workflow.Now(ctx)
137+
// workflow.ExecuteActivity(...).Get(ctx, nil) // takes 1 second to schedule, run, and schedule the new decision task
138+
// after := workflow.Now(ctx)
139+
// elapsed := after.Sub(before) // this will be 1 second or more (depending on when the decision task started).
140+
//
141+
// Some actions may also advance `workflow.Now(ctx)` to a new time, e.g. local activities update the time when they
142+
// complete. Generally speaking this occurs when there is a recorded event, as that event has a recorded time.
122143
func Now(ctx Context) time.Time {
123144
return internal.Now(ctx)
124145
}

0 commit comments

Comments
 (0)