Files
tasks/chasm/lib/scheduler/proto/v1/request_response.proto
Alex StanfieldandGitHub 223478bf8f V1 to CHASM scheduler migration RPC (#9261)
## What changed

Adds an admin RPC (`MigrateSchedule`) that migrates workflow-backed (V1)
schedulers to CHASM (V2) schedulers.

The flow:
1. Admin API signals the V1 scheduler workflow with `migrate-to-chasm`
2. V1 workflow runs a local activity that snapshots state and calls
`CreateFromMigrationState` on the CHASM scheduler service
3. On success, the V1 workflow closes. On failure, a `PendingMigration`
flag persists so the next run loop iteration retries automatically

Key details:
- `CreateSchedulerFromMigration` initializes the full CHASM scheduler
tree (generator, invoker, backfillers, visibility) from V1 state
- Running/completed workflows are converted to buffered starts; ongoing
backfills are preserved
- Migration is idempotent -- if the CHASM schedule already exists, it's
treated as success
- Metrics: `schedule_migration_started`, `schedule_migration_completed`,
`schedule_migration_failed` (with direction tag)
- Local activity uses 10m schedule-to-close timeout; retries happen at
the workflow level via the persistent flag

## Why

Needed for migrating existing V1 schedulers to CHASM without downtime or
data loss.

## Follow-up items

- V2 to V1 migration (rollback path)
- Sentinel key handling when `EnableCHASMSchedulerCreation` was
previously enabled
- Attach completion callbacks to running workflows after migration
2026-03-12 10:18:02 -05:00

84 lines
2.3 KiB
Protocol Buffer

syntax = "proto3";
package temporal.server.chasm.lib.scheduler.proto.v1;
option go_package = "go.temporal.io/server/chasm/lib/scheduler/gen/schedulerpb;schedulerpb";
import "temporal/api/workflowservice/v1/request_response.proto";
import "chasm/lib/scheduler/proto/v1/message.proto";
message CreateScheduleRequest {
// Internal namespace ID (UUID).
string namespace_id = 1;
temporal.api.workflowservice.v1.CreateScheduleRequest frontend_request = 2;
}
message CreateScheduleResponse {
temporal.api.workflowservice.v1.CreateScheduleResponse frontend_response = 1;
}
message UpdateScheduleRequest {
// Internal namespace ID (UUID).
string namespace_id = 1;
temporal.api.workflowservice.v1.UpdateScheduleRequest frontend_request = 2;
}
message UpdateScheduleResponse {
temporal.api.workflowservice.v1.UpdateScheduleResponse frontend_response = 1;
}
message PatchScheduleRequest {
// Internal namespace ID (UUID).
string namespace_id = 1;
temporal.api.workflowservice.v1.PatchScheduleRequest frontend_request = 2;
}
message PatchScheduleResponse {
temporal.api.workflowservice.v1.PatchScheduleResponse frontend_response = 1;
}
message DeleteScheduleRequest {
// Internal namespace ID (UUID).
string namespace_id = 1;
temporal.api.workflowservice.v1.DeleteScheduleRequest frontend_request = 2;
}
message DeleteScheduleResponse {
temporal.api.workflowservice.v1.DeleteScheduleResponse frontend_response = 1;
}
message DescribeScheduleRequest {
// Internal namespace ID (UUID).
string namespace_id = 1;
temporal.api.workflowservice.v1.DescribeScheduleRequest frontend_request = 2;
}
message DescribeScheduleResponse {
temporal.api.workflowservice.v1.DescribeScheduleResponse frontend_response = 1;
}
message ListScheduleMatchingTimesRequest {
// Internal namespace ID (UUID).
string namespace_id = 1;
temporal.api.workflowservice.v1.ListScheduleMatchingTimesRequest frontend_request = 2;
}
message ListScheduleMatchingTimesResponse {
temporal.api.workflowservice.v1.ListScheduleMatchingTimesResponse frontend_response = 1;
}
message CreateFromMigrationStateRequest {
// Internal namespace ID (UUID).
string namespace_id = 1;
SchedulerMigrationState state = 2;
}
message CreateFromMigrationStateResponse {}