diff --git a/README.md b/README.md
index b2881d1..611ee24 100644
--- a/README.md
+++ b/README.md
@@ -21,12 +21,12 @@ Atomizer is a modern, high-performance job scheduling and queueing framework for
- π **Graceful Shutdown** β Ensure in-flight jobs finish and pending batched jobs are safely released for re-processing during shutdowns.
- π¦ **Batch Processing** β Tune throughput with batch size and parallelism settings per queue.
- β³ **Visibility Timeout** β Prevent job duplication by locking jobs during processing.
+- π **FIFO Partitioned Processing** β Guarantee strict in-order, one-at-a-time execution per partition key (e.g. per customer, per entity).
- π§ͺ **In-Memory Driver** β Perfect for local development and testing; spin up queues instantly with zero setup.
- π **ASP.NET Core Integration** β Works with DI, logging, and modern C# idioms.
## Planned Features
- π **Dashboard** β Live monitoring, retry/dead-letter management, and operational insights.
-- π **FIFO Processing** β Guarantee jobs are processed in strict order, without overlap.
- β‘ **Redis Driver** β Lightning-fast, distributed, in-memory queues for massive scale.
## Quick Start
@@ -130,7 +130,20 @@ app.MapPost(
);
```
-### 5. Schedule Recurring Jobs
+### 5. FIFO Processing (Partitioned Jobs)
+To guarantee jobs for the same entity execute one-at-a-time in enqueue order, assign a `PartitionKey`:
+
+```csharp
+// All stock events for the same product are processed in strict FIFO order.
+await atomizerClient.EnqueueAsync(
+ new StockEvent(productId, "restock", delta: 50),
+ options => options.PartitionKey = new PartitionKey(productId.ToString())
+);
+```
+
+Jobs sharing the same `PartitionKey` and queue are serialized: the next job in the partition only starts after the previous one completes (or fails and is rescheduled). Unpartitioned jobs in the same queue are unaffected and continue to process in parallel.
+
+### 6. Schedule Recurring Jobs
in Program.cs:
```csharp
...
diff --git a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20250827145643_Initial.Designer.cs b/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20250827145643_Initial.Designer.cs
deleted file mode 100644
index ea93656..0000000
--- a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20250827145643_Initial.Designer.cs
+++ /dev/null
@@ -1,240 +0,0 @@
-ο»Ώ//
-using System;
-using Atomizer.EFCore.Example.Data.MySql;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Metadata;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-
-#nullable disable
-
-namespace Atomizer.EFCore.Example.Data.MySql.Migrations
-{
- [DbContext(typeof(ExampleMySqlContext))]
- [Migration("20250827145643_Initial")]
- partial class Initial
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "9.0.8")
- .HasAnnotation("Relational:MaxIdentifierLength", 64);
-
- MySqlModelBuilderExtensions.AutoIncrementColumns(modelBuilder);
-
- modelBuilder.Entity("Atomizer.EFCore.Example.Entities.Product", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("char(36)");
-
- b.Property("CreatedAt")
- .HasColumnType("datetime(6)");
-
- b.Property("Name")
- .IsRequired()
- .HasColumnType("longtext");
-
- b.Property("Price")
- .HasColumnType("decimal(65,30)");
-
- b.Property("Quantity")
- .HasColumnType("int");
-
- b.HasKey("Id");
-
- b.ToTable("Products");
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerJobEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("char(36)");
-
- b.Property("Attempts")
- .HasColumnType("int");
-
- b.Property("CompletedAt")
- .HasColumnType("datetime(6)");
-
- b.Property("CreatedAt")
- .HasColumnType("datetime(6)");
-
- b.Property("FailedAt")
- .HasColumnType("datetime(6)");
-
- b.Property("IdempotencyKey")
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
-
- b.Property("LeaseToken")
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
-
- b.Property("Payload")
- .IsRequired()
- .HasColumnType("longtext");
-
- b.Property("PayloadType")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("varchar(1024)");
-
- b.Property("QueueKey")
- .IsRequired()
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
-
- b.Property("RetryIntervals")
- .IsRequired()
- .HasMaxLength(4096)
- .HasColumnType("varchar(4096)");
-
- b.Property("ScheduleJobKey")
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
-
- b.Property("ScheduledAt")
- .HasColumnType("datetime(6)");
-
- b.Property("Status")
- .HasColumnType("int");
-
- b.Property("UpdatedAt")
- .HasColumnType("datetime(6)");
-
- b.Property("VisibleAt")
- .HasColumnType("datetime(6)");
-
- b.HasKey("Id");
-
- b.ToTable("AtomizerJobs", (string)null);
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerJobErrorEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("char(36)");
-
- b.Property("Attempt")
- .HasColumnType("int");
-
- b.Property("CreatedAt")
- .HasColumnType("datetime(6)");
-
- b.Property("ErrorMessage")
- .HasMaxLength(2048)
- .HasColumnType("varchar(2048)");
-
- b.Property("ExceptionType")
- .HasMaxLength(1024)
- .HasColumnType("varchar(1024)");
-
- b.Property("JobId")
- .HasColumnType("char(36)");
-
- b.Property("RuntimeIdentity")
- .HasMaxLength(255)
- .HasColumnType("varchar(255)");
-
- b.Property("StackTrace")
- .HasMaxLength(5120)
- .HasColumnType("varchar(5120)");
-
- b.HasKey("Id");
-
- b.HasIndex("JobId");
-
- b.ToTable("AtomizerJobErrors", (string)null);
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerScheduleEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("char(36)");
-
- b.Property("CreatedAt")
- .HasColumnType("datetime(6)");
-
- b.Property("Enabled")
- .HasColumnType("tinyint(1)");
-
- b.Property("JobKey")
- .IsRequired()
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
-
- b.Property("LastEnqueueAt")
- .HasColumnType("datetime(6)");
-
- b.Property("MaxCatchUp")
- .HasColumnType("int");
-
- b.Property("MisfirePolicy")
- .HasColumnType("int");
-
- b.Property("NextRunAt")
- .HasColumnType("datetime(6)");
-
- b.Property("Payload")
- .IsRequired()
- .HasColumnType("longtext");
-
- b.Property("PayloadType")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("varchar(1024)");
-
- b.Property("QueueKey")
- .IsRequired()
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
-
- b.Property("RetryIntervals")
- .IsRequired()
- .HasMaxLength(4096)
- .HasColumnType("varchar(4096)");
-
- b.Property("Schedule")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("varchar(1024)");
-
- b.Property("TimeZone")
- .IsRequired()
- .HasMaxLength(64)
- .HasColumnType("varchar(64)");
-
- b.Property("UpdatedAt")
- .HasColumnType("datetime(6)");
-
- b.HasKey("Id");
-
- b.ToTable("AtomizerSchedules", (string)null);
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerJobErrorEntity", b =>
- {
- b.HasOne("Atomizer.EntityFrameworkCore.Entities.AtomizerJobEntity", "Job")
- .WithMany("Errors")
- .HasForeignKey("JobId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Job");
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerJobEntity", b =>
- {
- b.Navigation("Errors");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20250827145643_Initial.cs b/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20250827145643_Initial.cs
deleted file mode 100644
index c768c0d..0000000
--- a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20250827145643_Initial.cs
+++ /dev/null
@@ -1,176 +0,0 @@
-ο»Ώusing System;
-using Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-namespace Atomizer.EFCore.Example.Data.MySql.Migrations
-{
- ///
- public partial class Initial : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AlterDatabase().Annotation("MySql:CharSet", "utf8mb4");
-
- migrationBuilder
- .CreateTable(
- name: "AtomizerJobs",
- columns: table => new
- {
- Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
- QueueKey = table
- .Column(type: "varchar(512)", maxLength: 512, nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- PayloadType = table
- .Column(type: "varchar(1024)", maxLength: 1024, nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- Payload = table
- .Column(type: "longtext", nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- ScheduledAt = table.Column(type: "datetime(6)", nullable: false),
- VisibleAt = table.Column(type: "datetime(6)", nullable: true),
- Status = table.Column(type: "int", nullable: false),
- Attempts = table.Column(type: "int", nullable: false),
- RetryIntervals = table
- .Column(type: "varchar(4096)", maxLength: 4096, nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- CreatedAt = table.Column(type: "datetime(6)", nullable: false),
- UpdatedAt = table.Column(type: "datetime(6)", nullable: false),
- CompletedAt = table.Column(type: "datetime(6)", nullable: true),
- FailedAt = table.Column(type: "datetime(6)", nullable: true),
- LeaseToken = table
- .Column(type: "varchar(512)", maxLength: 512, nullable: true)
- .Annotation("MySql:CharSet", "utf8mb4"),
- ScheduleJobKey = table
- .Column(type: "varchar(512)", maxLength: 512, nullable: true)
- .Annotation("MySql:CharSet", "utf8mb4"),
- IdempotencyKey = table
- .Column(type: "varchar(512)", maxLength: 512, nullable: true)
- .Annotation("MySql:CharSet", "utf8mb4"),
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AtomizerJobs", x => x.Id);
- }
- )
- .Annotation("MySql:CharSet", "utf8mb4");
-
- migrationBuilder
- .CreateTable(
- name: "AtomizerSchedules",
- columns: table => new
- {
- Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
- JobKey = table
- .Column(type: "varchar(512)", maxLength: 512, nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- QueueKey = table
- .Column(type: "varchar(512)", maxLength: 512, nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- PayloadType = table
- .Column(type: "varchar(1024)", maxLength: 1024, nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- Payload = table
- .Column(type: "longtext", nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- Schedule = table
- .Column(type: "varchar(1024)", maxLength: 1024, nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- TimeZone = table
- .Column(type: "varchar(64)", maxLength: 64, nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- MisfirePolicy = table.Column(type: "int", nullable: false),
- MaxCatchUp = table.Column(type: "int", nullable: false),
- Enabled = table.Column(type: "tinyint(1)", nullable: false),
- RetryIntervals = table
- .Column(type: "varchar(4096)", maxLength: 4096, nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- NextRunAt = table.Column(type: "datetime(6)", nullable: false),
- LastEnqueueAt = table.Column(type: "datetime(6)", nullable: true),
- CreatedAt = table.Column(type: "datetime(6)", nullable: false),
- UpdatedAt = table.Column(type: "datetime(6)", nullable: false),
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AtomizerSchedules", x => x.Id);
- }
- )
- .Annotation("MySql:CharSet", "utf8mb4");
-
- migrationBuilder
- .CreateTable(
- name: "Products",
- columns: table => new
- {
- Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
- Name = table
- .Column(type: "longtext", nullable: false)
- .Annotation("MySql:CharSet", "utf8mb4"),
- Price = table.Column(type: "decimal(65,30)", nullable: false),
- CreatedAt = table.Column(type: "datetime(6)", nullable: false),
- Quantity = table.Column(type: "int", nullable: false),
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_Products", x => x.Id);
- }
- )
- .Annotation("MySql:CharSet", "utf8mb4");
-
- migrationBuilder
- .CreateTable(
- name: "AtomizerJobErrors",
- columns: table => new
- {
- Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
- JobId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
- ErrorMessage = table
- .Column(type: "varchar(2048)", maxLength: 2048, nullable: true)
- .Annotation("MySql:CharSet", "utf8mb4"),
- StackTrace = table
- .Column(type: "varchar(5120)", maxLength: 5120, nullable: true)
- .Annotation("MySql:CharSet", "utf8mb4"),
- ExceptionType = table
- .Column(type: "varchar(1024)", maxLength: 1024, nullable: true)
- .Annotation("MySql:CharSet", "utf8mb4"),
- CreatedAt = table.Column(type: "datetime(6)", nullable: false),
- Attempt = table.Column(type: "int", nullable: false),
- RuntimeIdentity = table
- .Column(type: "varchar(255)", maxLength: 255, nullable: true)
- .Annotation("MySql:CharSet", "utf8mb4"),
- },
- constraints: table =>
- {
- table.PrimaryKey("PK_AtomizerJobErrors", x => x.Id);
- table.ForeignKey(
- name: "FK_AtomizerJobErrors_AtomizerJobs_JobId",
- column: x => x.JobId,
- principalTable: "AtomizerJobs",
- principalColumn: "Id",
- onDelete: ReferentialAction.Cascade
- );
- }
- )
- .Annotation("MySql:CharSet", "utf8mb4");
-
- migrationBuilder.CreateIndex(
- name: "IX_AtomizerJobErrors_JobId",
- table: "AtomizerJobErrors",
- column: "JobId"
- );
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropTable(name: "AtomizerJobErrors");
-
- migrationBuilder.DropTable(name: "AtomizerSchedules");
-
- migrationBuilder.DropTable(name: "Products");
-
- migrationBuilder.DropTable(name: "AtomizerJobs");
- }
- }
-}
diff --git a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260503193358_AddIndexForJobKeyOnSchedulesTable.cs b/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260503193358_AddIndexForJobKeyOnSchedulesTable.cs
deleted file mode 100644
index cd10b04..0000000
--- a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260503193358_AddIndexForJobKeyOnSchedulesTable.cs
+++ /dev/null
@@ -1,76 +0,0 @@
-ο»Ώusing Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-namespace Atomizer.EFCore.Example.Data.MySql.Migrations
-{
- ///
- public partial class AddIndexForJobKeyOnSchedulesTable : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AlterColumn(
- name: "QueueKey",
- table: "AtomizerSchedules",
- type: "varchar(100)",
- maxLength: 100,
- nullable: false,
- oldClrType: typeof(string),
- oldType: "varchar(512)",
- oldMaxLength: 512)
- .Annotation("MySql:CharSet", "utf8mb4")
- .OldAnnotation("MySql:CharSet", "utf8mb4");
-
- migrationBuilder.AlterColumn(
- name: "JobKey",
- table: "AtomizerSchedules",
- type: "varchar(255)",
- maxLength: 255,
- nullable: false,
- oldClrType: typeof(string),
- oldType: "varchar(512)",
- oldMaxLength: 512)
- .Annotation("MySql:CharSet", "utf8mb4")
- .OldAnnotation("MySql:CharSet", "utf8mb4");
-
- migrationBuilder.CreateIndex(
- name: "IX_AtomizerSchedules_JobKey",
- table: "AtomizerSchedules",
- column: "JobKey",
- unique: true);
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropIndex(
- name: "IX_AtomizerSchedules_JobKey",
- table: "AtomizerSchedules");
-
- migrationBuilder.AlterColumn(
- name: "QueueKey",
- table: "AtomizerSchedules",
- type: "varchar(512)",
- maxLength: 512,
- nullable: false,
- oldClrType: typeof(string),
- oldType: "varchar(100)",
- oldMaxLength: 100)
- .Annotation("MySql:CharSet", "utf8mb4")
- .OldAnnotation("MySql:CharSet", "utf8mb4");
-
- migrationBuilder.AlterColumn(
- name: "JobKey",
- table: "AtomizerSchedules",
- type: "varchar(512)",
- maxLength: 512,
- nullable: false,
- oldClrType: typeof(string),
- oldType: "varchar(255)",
- oldMaxLength: 255)
- .Annotation("MySql:CharSet", "utf8mb4")
- .OldAnnotation("MySql:CharSet", "utf8mb4");
- }
- }
-}
diff --git a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260503193358_AddIndexForJobKeyOnSchedulesTable.Designer.cs b/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260504193620_Initial.Designer.cs
similarity index 94%
rename from samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260503193358_AddIndexForJobKeyOnSchedulesTable.Designer.cs
rename to samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260504193620_Initial.Designer.cs
index 24c4a77..1d93d78 100644
--- a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260503193358_AddIndexForJobKeyOnSchedulesTable.Designer.cs
+++ b/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260504193620_Initial.Designer.cs
@@ -12,8 +12,8 @@
namespace Atomizer.EFCore.Example.Data.MySql.Migrations
{
[DbContext(typeof(ExampleMySqlContext))]
- [Migration("20260503193358_AddIndexForJobKeyOnSchedulesTable")]
- partial class AddIndexForJobKeyOnSchedulesTable
+ [Migration("20260504193620_Initial")]
+ partial class Initial
{
///
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -75,6 +75,10 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
.HasMaxLength(512)
.HasColumnType("varchar(512)");
+ b.Property("PartitionKey")
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)");
+
b.Property("Payload")
.IsRequired()
.HasColumnType("longtext");
@@ -86,8 +90,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
b.Property("QueueKey")
.IsRequired()
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)");
b.Property("RetryIntervals")
.IsRequired()
@@ -95,12 +99,15 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
.HasColumnType("varchar(4096)");
b.Property("ScheduleJobKey")
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)");
b.Property("ScheduledAt")
.HasColumnType("datetime(6)");
+ b.Property("SequenceNumber")
+ .HasColumnType("bigint");
+
b.Property("Status")
.HasColumnType("int");
diff --git a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260504193620_Initial.cs b/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260504193620_Initial.cs
new file mode 100644
index 0000000..14ccf33
--- /dev/null
+++ b/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/20260504193620_Initial.cs
@@ -0,0 +1,161 @@
+ο»Ώusing System;
+using Microsoft.EntityFrameworkCore.Migrations;
+
+#nullable disable
+
+namespace Atomizer.EFCore.Example.Data.MySql.Migrations
+{
+ ///
+ public partial class Initial : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterDatabase()
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "AtomizerJobs",
+ columns: table => new
+ {
+ Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
+ QueueKey = table.Column(type: "varchar(100)", maxLength: 100, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ PayloadType = table.Column(type: "varchar(1024)", maxLength: 1024, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Payload = table.Column(type: "longtext", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ ScheduledAt = table.Column(type: "datetime(6)", nullable: false),
+ VisibleAt = table.Column(type: "datetime(6)", nullable: true),
+ Status = table.Column(type: "int", nullable: false),
+ Attempts = table.Column(type: "int", nullable: false),
+ RetryIntervals = table.Column(type: "varchar(4096)", maxLength: 4096, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ CreatedAt = table.Column(type: "datetime(6)", nullable: false),
+ UpdatedAt = table.Column(type: "datetime(6)", nullable: false),
+ CompletedAt = table.Column(type: "datetime(6)", nullable: true),
+ FailedAt = table.Column(type: "datetime(6)", nullable: true),
+ LeaseToken = table.Column(type: "varchar(512)", maxLength: 512, nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ ScheduleJobKey = table.Column(type: "varchar(255)", maxLength: 255, nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ IdempotencyKey = table.Column(type: "varchar(512)", maxLength: 512, nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ PartitionKey = table.Column(type: "varchar(255)", maxLength: 255, nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ SequenceNumber = table.Column(type: "bigint", nullable: true)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AtomizerJobs", x => x.Id);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "AtomizerSchedules",
+ columns: table => new
+ {
+ Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
+ JobKey = table.Column(type: "varchar(255)", maxLength: 255, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ QueueKey = table.Column(type: "varchar(100)", maxLength: 100, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ PayloadType = table.Column(type: "varchar(1024)", maxLength: 1024, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Payload = table.Column(type: "longtext", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Schedule = table.Column(type: "varchar(1024)", maxLength: 1024, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ TimeZone = table.Column(type: "varchar(64)", maxLength: 64, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ MisfirePolicy = table.Column(type: "int", nullable: false),
+ MaxCatchUp = table.Column(type: "int", nullable: false),
+ Enabled = table.Column(type: "tinyint(1)", nullable: false),
+ RetryIntervals = table.Column(type: "varchar(4096)", maxLength: 4096, nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ NextRunAt = table.Column(type: "datetime(6)", nullable: false),
+ LastEnqueueAt = table.Column(type: "datetime(6)", nullable: true),
+ CreatedAt = table.Column(type: "datetime(6)", nullable: false),
+ UpdatedAt = table.Column(type: "datetime(6)", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AtomizerSchedules", x => x.Id);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "Products",
+ columns: table => new
+ {
+ Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
+ Name = table.Column(type: "longtext", nullable: false)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ Price = table.Column(type: "decimal(65,30)", nullable: false),
+ CreatedAt = table.Column(type: "datetime(6)", nullable: false),
+ Quantity = table.Column(type: "int", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_Products", x => x.Id);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateTable(
+ name: "AtomizerJobErrors",
+ columns: table => new
+ {
+ Id = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
+ JobId = table.Column(type: "char(36)", nullable: false, collation: "ascii_general_ci"),
+ ErrorMessage = table.Column(type: "varchar(2048)", maxLength: 2048, nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ StackTrace = table.Column(type: "varchar(5120)", maxLength: 5120, nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ ExceptionType = table.Column(type: "varchar(1024)", maxLength: 1024, nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4"),
+ CreatedAt = table.Column(type: "datetime(6)", nullable: false),
+ Attempt = table.Column(type: "int", nullable: false),
+ RuntimeIdentity = table.Column(type: "varchar(255)", maxLength: 255, nullable: true)
+ .Annotation("MySql:CharSet", "utf8mb4")
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_AtomizerJobErrors", x => x.Id);
+ table.ForeignKey(
+ name: "FK_AtomizerJobErrors_AtomizerJobs_JobId",
+ column: x => x.JobId,
+ principalTable: "AtomizerJobs",
+ principalColumn: "Id",
+ onDelete: ReferentialAction.Cascade);
+ })
+ .Annotation("MySql:CharSet", "utf8mb4");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AtomizerJobErrors_JobId",
+ table: "AtomizerJobErrors",
+ column: "JobId");
+
+ migrationBuilder.CreateIndex(
+ name: "IX_AtomizerSchedules_JobKey",
+ table: "AtomizerSchedules",
+ column: "JobKey",
+ unique: true);
+ }
+
+ ///
+ protected override void Down(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.DropTable(
+ name: "AtomizerJobErrors");
+
+ migrationBuilder.DropTable(
+ name: "AtomizerSchedules");
+
+ migrationBuilder.DropTable(
+ name: "Products");
+
+ migrationBuilder.DropTable(
+ name: "AtomizerJobs");
+ }
+ }
+}
diff --git a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/ExampleMySqlContextModelSnapshot.cs b/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/ExampleMySqlContextModelSnapshot.cs
index 1840d7b..7a03282 100644
--- a/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/ExampleMySqlContextModelSnapshot.cs
+++ b/samples/Atomizer.EFCore.Example/Data/MySql/Migrations/ExampleMySqlContextModelSnapshot.cs
@@ -72,6 +72,10 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasMaxLength(512)
.HasColumnType("varchar(512)");
+ b.Property("PartitionKey")
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)");
+
b.Property("Payload")
.IsRequired()
.HasColumnType("longtext");
@@ -83,8 +87,8 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.Property("QueueKey")
.IsRequired()
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
+ .HasMaxLength(100)
+ .HasColumnType("varchar(100)");
b.Property("RetryIntervals")
.IsRequired()
@@ -92,12 +96,15 @@ protected override void BuildModel(ModelBuilder modelBuilder)
.HasColumnType("varchar(4096)");
b.Property("ScheduleJobKey")
- .HasMaxLength(512)
- .HasColumnType("varchar(512)");
+ .HasMaxLength(255)
+ .HasColumnType("varchar(255)");
b.Property("ScheduledAt")
.HasColumnType("datetime(6)");
+ b.Property("SequenceNumber")
+ .HasColumnType("bigint");
+
b.Property("Status")
.HasColumnType("int");
diff --git a/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20250827145628_Initial.Designer.cs b/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20250827145628_Initial.Designer.cs
deleted file mode 100644
index f4bcd5b..0000000
--- a/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20250827145628_Initial.Designer.cs
+++ /dev/null
@@ -1,240 +0,0 @@
-ο»Ώ//
-using System;
-using Atomizer.EFCore.Example.Data.Postgres;
-using Microsoft.EntityFrameworkCore;
-using Microsoft.EntityFrameworkCore.Infrastructure;
-using Microsoft.EntityFrameworkCore.Migrations;
-using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
-using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
-
-#nullable disable
-
-namespace Atomizer.EFCore.Example.Data.Postgres.Migrations
-{
- [DbContext(typeof(ExamplePostgresContext))]
- [Migration("20250827145628_Initial")]
- partial class Initial
- {
- ///
- protected override void BuildTargetModel(ModelBuilder modelBuilder)
- {
-#pragma warning disable 612, 618
- modelBuilder
- .HasAnnotation("ProductVersion", "9.0.8")
- .HasAnnotation("Relational:MaxIdentifierLength", 63);
-
- NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
-
- modelBuilder.Entity("Atomizer.EFCore.Example.Entities.Product", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Name")
- .IsRequired()
- .HasColumnType("text");
-
- b.Property("Price")
- .HasColumnType("numeric");
-
- b.Property("Quantity")
- .HasColumnType("integer");
-
- b.HasKey("Id");
-
- b.ToTable("Products");
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerJobEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("Attempts")
- .HasColumnType("integer");
-
- b.Property("CompletedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("FailedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("IdempotencyKey")
- .HasMaxLength(512)
- .HasColumnType("character varying(512)");
-
- b.Property("LeaseToken")
- .HasMaxLength(512)
- .HasColumnType("character varying(512)");
-
- b.Property("Payload")
- .IsRequired()
- .HasColumnType("text");
-
- b.Property("PayloadType")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("character varying(1024)");
-
- b.Property("QueueKey")
- .IsRequired()
- .HasMaxLength(512)
- .HasColumnType("character varying(512)");
-
- b.Property("RetryIntervals")
- .IsRequired()
- .HasMaxLength(4096)
- .HasColumnType("character varying(4096)");
-
- b.Property("ScheduleJobKey")
- .HasMaxLength(512)
- .HasColumnType("character varying(512)");
-
- b.Property("ScheduledAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Status")
- .HasColumnType("integer");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("VisibleAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.ToTable("AtomizerJobs", "Atomizer");
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerJobErrorEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("Attempt")
- .HasColumnType("integer");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("ErrorMessage")
- .HasMaxLength(2048)
- .HasColumnType("character varying(2048)");
-
- b.Property("ExceptionType")
- .HasMaxLength(1024)
- .HasColumnType("character varying(1024)");
-
- b.Property("JobId")
- .HasColumnType("uuid");
-
- b.Property("RuntimeIdentity")
- .HasMaxLength(255)
- .HasColumnType("character varying(255)");
-
- b.Property("StackTrace")
- .HasMaxLength(5120)
- .HasColumnType("character varying(5120)");
-
- b.HasKey("Id");
-
- b.HasIndex("JobId");
-
- b.ToTable("AtomizerJobErrors", "Atomizer");
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerScheduleEntity", b =>
- {
- b.Property("Id")
- .ValueGeneratedOnAdd()
- .HasColumnType("uuid");
-
- b.Property("CreatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Enabled")
- .HasColumnType("boolean");
-
- b.Property("JobKey")
- .IsRequired()
- .HasMaxLength(512)
- .HasColumnType("character varying(512)");
-
- b.Property("LastEnqueueAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("MaxCatchUp")
- .HasColumnType("integer");
-
- b.Property("MisfirePolicy")
- .HasColumnType("integer");
-
- b.Property("NextRunAt")
- .HasColumnType("timestamp with time zone");
-
- b.Property("Payload")
- .IsRequired()
- .HasColumnType("text");
-
- b.Property("PayloadType")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("character varying(1024)");
-
- b.Property("QueueKey")
- .IsRequired()
- .HasMaxLength(512)
- .HasColumnType("character varying(512)");
-
- b.Property("RetryIntervals")
- .IsRequired()
- .HasMaxLength(4096)
- .HasColumnType("character varying(4096)");
-
- b.Property("Schedule")
- .IsRequired()
- .HasMaxLength(1024)
- .HasColumnType("character varying(1024)");
-
- b.Property("TimeZone")
- .IsRequired()
- .HasMaxLength(64)
- .HasColumnType("character varying(64)");
-
- b.Property("UpdatedAt")
- .HasColumnType("timestamp with time zone");
-
- b.HasKey("Id");
-
- b.ToTable("AtomizerSchedules", "Atomizer");
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerJobErrorEntity", b =>
- {
- b.HasOne("Atomizer.EntityFrameworkCore.Entities.AtomizerJobEntity", "Job")
- .WithMany("Errors")
- .HasForeignKey("JobId")
- .OnDelete(DeleteBehavior.Cascade)
- .IsRequired();
-
- b.Navigation("Job");
- });
-
- modelBuilder.Entity("Atomizer.EntityFrameworkCore.Entities.AtomizerJobEntity", b =>
- {
- b.Navigation("Errors");
- });
-#pragma warning restore 612, 618
- }
- }
-}
diff --git a/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260503193345_AddIndexForJobKeyOnSchedulesTable.cs b/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260503193345_AddIndexForJobKeyOnSchedulesTable.cs
deleted file mode 100644
index 85bbb0d..0000000
--- a/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260503193345_AddIndexForJobKeyOnSchedulesTable.cs
+++ /dev/null
@@ -1,74 +0,0 @@
-ο»Ώusing Microsoft.EntityFrameworkCore.Migrations;
-
-#nullable disable
-
-namespace Atomizer.EFCore.Example.Data.Postgres.Migrations
-{
- ///
- public partial class AddIndexForJobKeyOnSchedulesTable : Migration
- {
- ///
- protected override void Up(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.AlterColumn(
- name: "QueueKey",
- schema: "Atomizer",
- table: "AtomizerSchedules",
- type: "character varying(100)",
- maxLength: 100,
- nullable: false,
- oldClrType: typeof(string),
- oldType: "character varying(512)",
- oldMaxLength: 512);
-
- migrationBuilder.AlterColumn(
- name: "JobKey",
- schema: "Atomizer",
- table: "AtomizerSchedules",
- type: "character varying(255)",
- maxLength: 255,
- nullable: false,
- oldClrType: typeof(string),
- oldType: "character varying(512)",
- oldMaxLength: 512);
-
- migrationBuilder.CreateIndex(
- name: "IX_AtomizerSchedules_JobKey",
- schema: "Atomizer",
- table: "AtomizerSchedules",
- column: "JobKey",
- unique: true);
- }
-
- ///
- protected override void Down(MigrationBuilder migrationBuilder)
- {
- migrationBuilder.DropIndex(
- name: "IX_AtomizerSchedules_JobKey",
- schema: "Atomizer",
- table: "AtomizerSchedules");
-
- migrationBuilder.AlterColumn(
- name: "QueueKey",
- schema: "Atomizer",
- table: "AtomizerSchedules",
- type: "character varying(512)",
- maxLength: 512,
- nullable: false,
- oldClrType: typeof(string),
- oldType: "character varying(100)",
- oldMaxLength: 100);
-
- migrationBuilder.AlterColumn(
- name: "JobKey",
- schema: "Atomizer",
- table: "AtomizerSchedules",
- type: "character varying(512)",
- maxLength: 512,
- nullable: false,
- oldClrType: typeof(string),
- oldType: "character varying(255)",
- oldMaxLength: 255);
- }
- }
-}
diff --git a/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260503193345_AddIndexForJobKeyOnSchedulesTable.Designer.cs b/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260504193605_Initial.Designer.cs
similarity index 94%
rename from samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260503193345_AddIndexForJobKeyOnSchedulesTable.Designer.cs
rename to samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260504193605_Initial.Designer.cs
index 667ace1..2b18890 100644
--- a/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260503193345_AddIndexForJobKeyOnSchedulesTable.Designer.cs
+++ b/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260504193605_Initial.Designer.cs
@@ -12,8 +12,8 @@
namespace Atomizer.EFCore.Example.Data.Postgres.Migrations
{
[DbContext(typeof(ExamplePostgresContext))]
- [Migration("20260503193345_AddIndexForJobKeyOnSchedulesTable")]
- partial class AddIndexForJobKeyOnSchedulesTable
+ [Migration("20260504193605_Initial")]
+ partial class Initial
{
///
protected override void BuildTargetModel(ModelBuilder modelBuilder)
@@ -75,6 +75,10 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
.HasMaxLength(512)
.HasColumnType("character varying(512)");
+ b.Property("PartitionKey")
+ .HasMaxLength(255)
+ .HasColumnType("character varying(255)");
+
b.Property("Payload")
.IsRequired()
.HasColumnType("text");
@@ -86,8 +90,8 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
b.Property("QueueKey")
.IsRequired()
- .HasMaxLength(512)
- .HasColumnType("character varying(512)");
+ .HasMaxLength(100)
+ .HasColumnType("character varying(100)");
b.Property("RetryIntervals")
.IsRequired()
@@ -95,12 +99,15 @@ protected override void BuildTargetModel(ModelBuilder modelBuilder)
.HasColumnType("character varying(4096)");
b.Property("ScheduleJobKey")
- .HasMaxLength(512)
- .HasColumnType("character varying(512)");
+ .HasMaxLength(255)
+ .HasColumnType("character varying(255)");
b.Property("ScheduledAt")
.HasColumnType("timestamp with time zone");
+ b.Property("SequenceNumber")
+ .HasColumnType("bigint");
+
b.Property("Status")
.HasColumnType("integer");
diff --git a/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20250827145628_Initial.cs b/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260504193605_Initial.cs
similarity index 65%
rename from samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20250827145628_Initial.cs
rename to samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260504193605_Initial.cs
index 93ba47b..2503b82 100644
--- a/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20250827145628_Initial.cs
+++ b/samples/Atomizer.EFCore.Example/Data/Postgres/Migrations/20260504193605_Initial.cs
@@ -11,7 +11,8 @@ public partial class Initial : Migration
///
protected override void Up(MigrationBuilder migrationBuilder)
{
- migrationBuilder.EnsureSchema(name: "Atomizer");
+ migrationBuilder.EnsureSchema(
+ name: "Atomizer");
migrationBuilder.CreateTable(
name: "AtomizerJobs",
@@ -19,43 +20,28 @@ protected override void Up(MigrationBuilder migrationBuilder)
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false),
- QueueKey = table.Column(type: "character varying(512)", maxLength: 512, nullable: false),
- PayloadType = table.Column(
- type: "character varying(1024)",
- maxLength: 1024,
- nullable: false
- ),
+ QueueKey = table.Column(type: "character varying(100)", maxLength: 100, nullable: false),
+ PayloadType = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: false),
Payload = table.Column(type: "text", nullable: false),
ScheduledAt = table.Column(type: "timestamp with time zone", nullable: false),
VisibleAt = table.Column(type: "timestamp with time zone", nullable: true),
Status = table.Column(type: "integer", nullable: false),
Attempts = table.Column(type: "integer", nullable: false),
- RetryIntervals = table.Column(
- type: "character varying(4096)",
- maxLength: 4096,
- nullable: false
- ),
+ RetryIntervals = table.Column(type: "character varying(4096)", maxLength: 4096, nullable: false),
CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false),
CompletedAt = table.Column(type: "timestamp with time zone", nullable: true),
FailedAt = table.Column(type: "timestamp with time zone", nullable: true),
LeaseToken = table.Column(type: "character varying(512)", maxLength: 512, nullable: true),
- ScheduleJobKey = table.Column(
- type: "character varying(512)",
- maxLength: 512,
- nullable: true
- ),
- IdempotencyKey = table.Column(
- type: "character varying(512)",
- maxLength: 512,
- nullable: true
- ),
+ ScheduleJobKey = table.Column(type: "character varying(255)", maxLength: 255, nullable: true),
+ IdempotencyKey = table.Column(type: "character varying(512)", maxLength: 512, nullable: true),
+ PartitionKey = table.Column(type: "character varying(255)", maxLength: 255, nullable: true),
+ SequenceNumber = table.Column(type: "bigint", nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AtomizerJobs", x => x.Id);
- }
- );
+ });
migrationBuilder.CreateTable(
name: "AtomizerSchedules",
@@ -63,34 +49,25 @@ protected override void Up(MigrationBuilder migrationBuilder)
columns: table => new
{
Id = table.Column(type: "uuid", nullable: false),
- JobKey = table.Column(type: "character varying(512)", maxLength: 512, nullable: false),
- QueueKey = table.Column(type: "character varying(512)", maxLength: 512, nullable: false),
- PayloadType = table.Column(
- type: "character varying(1024)",
- maxLength: 1024,
- nullable: false
- ),
+ JobKey = table.Column(type: "character varying(255)", maxLength: 255, nullable: false),
+ QueueKey = table.Column(type: "character varying(100)", maxLength: 100, nullable: false),
+ PayloadType = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: false),
Payload = table.Column(type: "text", nullable: false),
Schedule = table.Column(type: "character varying(1024)", maxLength: 1024, nullable: false),
TimeZone = table.Column(type: "character varying(64)", maxLength: 64, nullable: false),
MisfirePolicy = table.Column(type: "integer", nullable: false),
MaxCatchUp = table.Column(type: "integer", nullable: false),
Enabled = table.Column(type: "boolean", nullable: false),
- RetryIntervals = table.Column(
- type: "character varying(4096)",
- maxLength: 4096,
- nullable: false
- ),
+ RetryIntervals = table.Column(type: "character varying(4096)", maxLength: 4096, nullable: false),
NextRunAt = table.Column(type: "timestamp with time zone", nullable: false),
LastEnqueueAt = table.Column(type: "timestamp with time zone", nullable: true),
CreatedAt = table.Column(type: "timestamp with time zone", nullable: false),
- UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false),
+ UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AtomizerSchedules", x => x.Id);
- }
- );
+ });
migrationBuilder.CreateTable(
name: "Products",
@@ -100,13 +77,12 @@ protected override void Up(MigrationBuilder migrationBuilder)
Name = table.Column(type: "text", nullable: false),
Price = table.Column