mirror of
https://github.com/hanzoai/tasks.git
synced 2026-11-03 03:56:04 +00:00
## 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
45 lines
2.3 KiB
Protocol Buffer
45 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 "chasm/lib/scheduler/proto/v1/request_response.proto";
|
|
import "temporal/server/api/routing/v1/extension.proto";
|
|
import "temporal/server/api/common/v1/api_category.proto";
|
|
|
|
service SchedulerService {
|
|
rpc CreateSchedule(CreateScheduleRequest) returns (CreateScheduleResponse) {
|
|
option (temporal.server.api.routing.v1.routing).business_id = "frontend_request.schedule_id";
|
|
option (temporal.server.api.common.v1.api_category).category = API_CATEGORY_STANDARD;
|
|
}
|
|
|
|
rpc UpdateSchedule(UpdateScheduleRequest) returns (UpdateScheduleResponse) {
|
|
option (temporal.server.api.routing.v1.routing).business_id = "frontend_request.schedule_id";
|
|
option (temporal.server.api.common.v1.api_category).category = API_CATEGORY_STANDARD;
|
|
}
|
|
|
|
rpc PatchSchedule(PatchScheduleRequest) returns (PatchScheduleResponse) {
|
|
option (temporal.server.api.routing.v1.routing).business_id = "frontend_request.schedule_id";
|
|
option (temporal.server.api.common.v1.api_category).category = API_CATEGORY_STANDARD;
|
|
}
|
|
|
|
rpc DeleteSchedule(DeleteScheduleRequest) returns (DeleteScheduleResponse) {
|
|
option (temporal.server.api.routing.v1.routing).business_id = "frontend_request.schedule_id";
|
|
option (temporal.server.api.common.v1.api_category).category = API_CATEGORY_STANDARD;
|
|
}
|
|
|
|
rpc DescribeSchedule(DescribeScheduleRequest) returns (DescribeScheduleResponse) {
|
|
option (temporal.server.api.routing.v1.routing).business_id = "frontend_request.schedule_id";
|
|
option (temporal.server.api.common.v1.api_category).category = API_CATEGORY_STANDARD;
|
|
}
|
|
|
|
rpc ListScheduleMatchingTimes(ListScheduleMatchingTimesRequest) returns (ListScheduleMatchingTimesResponse) {
|
|
option (temporal.server.api.routing.v1.routing).business_id = "frontend_request.schedule_id";
|
|
option (temporal.server.api.common.v1.api_category).category = API_CATEGORY_STANDARD;
|
|
}
|
|
rpc CreateFromMigrationState(CreateFromMigrationStateRequest) returns (CreateFromMigrationStateResponse) {
|
|
option (temporal.server.api.routing.v1.routing).business_id = "state.scheduler_state.schedule_id";
|
|
}
|
|
}
|