The Temporal Migrations Framework allows you to create and manage migration across your cloud-native solution. This framework, inspired by FluentMigrator, leverages the power of Temporal.io for building reliable and scalable workflows.
Temporal Migrations Framework is designed to facilitate the creation, management, and execution of migrations in cloud-native applications. By using Temporal.io's workflow and activity model, this framework ensures migrations are executed reliably and can be monitored effectively.
- Seamless Migration Creation: Define migrations using simple interface and attribute system.
- Temporal.io Integration: Leverage Temporal.io workflows and activities for reliable migration execution.
Install-Package InfinityFlow.Temporal.Migrator
var builder = Host.CreateApplicationBuilder(args);
builder
.Services
.AddTemporalMigrations();
var builder = Host.CreateApplicationBuilder(args);
builder
.Services
.AddTemporalMigrations()
.ConfigureClientOptions(builder => ...);
Default options include OpenTelemetry
interceptor, and Type
serializer needed for migrations to work.
It is possible to specify in which assemblies to scan for migrations
var builder = Host.CreateApplicationBuilder(args);
builder
.Services
.AddTemporalMigrations()
.ConfigureMigratorOptions(builder => builder
.AddAssemblies(typeof(M1).Assembly, typeof(M2).Assembly));
[Migration(1)]
public class M1 : IMigration
{
public ValueTask ExecuteAsync(CancellationToken cancellationToken)
{
// Code to run
return ValueTask.CompletedTask;
}
}
var client = serviceProvider.GetRequiredKeyedService<ITemporalClient>(MigrationOptions.DefaultTaskQueue);
await client.ExecuteMigration(new WorkflowOptions { Id = "migration", });
As migration is workflow class, you can start or execute child workflows, or use activities, in this case you have to register your workflows and activities
var builder = Host.CreateApplicationBuilder(args);
builder
.Services
.AddTemporalMigrations()
.ConfigureWorkerOptions(options => options
.AddWorkflow<MyWorkflow>());
[Migration(1)]
public class M1 : IMigration
{
/// <inheritdoc />
public async ValueTask ExecuteAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
await Workflow.ExecuteChildWorkflowAsync<MyWorkflow>(workflow => workflow.MyMethod(),
new ChildWorkflowOptions { Id = "my_child_workflow_id" });
return ValueTask.CompletedTask;
}
}
Unlike workflow which only support deterministic execution, activity allows dependency injection with all lifetimes:
- Singleton
AddSingletonActivities<T>
- Transient
AddTransientActivities<T>
- Scoped
AddScopedActivities<T>
var builder = Host.CreateApplicationBuilder(args);
builder
.Services
.AddTemporalMigrations()
.ConfigureWorkerOptions(options => options
.AddScopedActivities<MyActivities>());
[Migration(1)]
public class M1 : IMigration
{
/// <inheritdoc />
public async ValueTask ExecuteAsync(CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
await Workflow.ExecuteActivityAsync<MyActivities>(activity => activity.MyMethod(),
new ActivityOptions { ActivityId = "my_activitiy_id" });
return ValueTask.CompletedTask;
}
}
If you'd like to contribute to temporal-migrator please fork the repository and make changes as you'd like. Pull requests are warmly welcome.
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.