Skip to content

feat: adding log for v2 schedule migration pathway - #12145

Open
davidporter-id-au wants to merge 1 commit into
temporalio:mainfrom
davidporter-id-au:feature/log-for-migration
Open

davidporter-id-au wants to merge 1 commit into
temporalio:mainfrom
davidporter-id-au:feature/log-for-migration

Conversation

@davidporter-id-au

Copy link
Copy Markdown
Contributor

What changed?

Adds a log for V2 schedules when they migrate, to differentiate between being created vs migrated

How did you test it?

  • built
  • run locally and tested manually
  • covered by existing tests
  • added new unit test(s)
  • added new functional test(s)

Potential risks

low risk, just a log

@davidporter-id-au
davidporter-id-au requested a review from a team as a code owner September 18, 2026 05:59
@github-actions

github-actions Bot commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

Claude finished @davidporter-id-au's task in 2m 47s —— View job


Reviewed 2 files, 3 findings.
feature/log-for-migration

@davidporter-id-au davidporter-id-au changed the title adding log feat: adding log for v2 schedule migration pathway Sep 18, 2026
EventLog: chasm.NewComponentField(ctx, NewEventLog(ctx)),
}
sched.setNullableFields()
sched.getOrCreateEventLog(ctx).LogEvent(ctx, "created via migration from V1")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small — The event log is bounded and drops oldest-first, so this entry is the first one evicted; the created-vs-migrated signal disappears on exactly the schedules you'd want it for.

LogEvent keeps at most EventLogMaxEntries (30 by default, config.go:97) per component and drops the earliest entries beyond that. This event is written at construction, so it is always the first candidate for eviction from the Scheduler component's log. The same log also receives paused via API / unpaused via API (scheduler.go:228, :233), updated via API (:895), started migration to V1 (:840), schedule closed from idle timer (scheduler_tasks.go:57) and ignored-callback entries (completion.go:99). After 30 such events on a long-lived migrated schedule, there is no longer any way to tell it apart from one created through CreateScheduler, which logs nothing.

Distinguishing origin also relies on the absence of an event, which is ambiguous by construction: "created normally", "migrated but the entry aged out", and "created before this code shipped" all look identical.

Suggestion: If origin needs to survive, record it durably instead of (or in addition to) the event — e.g. a bool migrated_from_workflow on SchedulerState, set here and exposed in ListInfo/describe. If a best-effort breadcrumb is genuinely all that's wanted, log the counterpart on the CreateScheduler path too so the two paths are distinguished by a present event rather than a missing one.

EventLog: chasm.NewComponentField(ctx, NewEventLog(ctx)),
}
sched.setNullableFields()
sched.getOrCreateEventLog(ctx).LogEvent(ctx, "created via migration from V1")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitgetOrCreateEventLog re-checks a field that was just assigned unconditionally two lines above.

EventLog is set in the struct literal at line 311, so getOrCreateEventLog's TryGet-miss branch is unreachable here. The other call sites need it because they run against components that may have been loaded from persistence without an event log; this one does not.

Suggestion:

Suggested change
sched.getOrCreateEventLog(ctx).LogEvent(ctx, "created via migration from V1")
sched.EventLog.Get(ctx).LogEvent(ctx, "created via migration from V1")

Comment on lines +116 to +120
func TestCreateScheduler_NoMigrationEvent(t *testing.T) {
sched, ctx, _ := setupSchedulerForTest(t)

require.Empty(t, sched.EventLog.Get(ctx).Events)
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small — This test never calls CreateScheduler, and its whole body asserts an absence, so it will fail for reasons unrelated to migration.

setupSchedulerForTest calls scheduler.NewScheduler(...) with a nil patch (helper_test.go:633), not CreateScheduler, so the name points at a function the test does not exercise. TestCreateScheduler_InitialPauseState directly above does go through CreateScheduler, which makes the mismatch easy to misread.

The assertion is also a global claim about the create path rather than about migration: adding any event to NewScheduler — a future created via API counterpart, or an event from applyPausePatch if the helper ever passes a patch — breaks a test whose name says it is about migration events.

Suggestion: Name it for what it covers, and say what it protects:

Suggested change
func TestCreateScheduler_NoMigrationEvent(t *testing.T) {
sched, ctx, _ := setupSchedulerForTest(t)
require.Empty(t, sched.EventLog.Get(ctx).Events)
}
// TestNewScheduler_LogsNoEvents verifies the non-migration create path leaves
// the event log empty, so a "created via migration from V1" entry unambiguously
// identifies a migrated schedule.
func TestNewScheduler_LogsNoEvents(t *testing.T) {
sched, ctx, _ := setupSchedulerForTest(t)
require.Empty(t, sched.EventLog.Get(ctx).Events)
}

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant