Add background code migration service (#26652)
This commit is contained in:
59
packages/opencode/src/data-migration.ts
Normal file
59
packages/opencode/src/data-migration.ts
Normal file
@@ -0,0 +1,59 @@
|
||||
import { Context, Effect, Layer } from "effect"
|
||||
import { Database } from "./storage/db"
|
||||
import { DataMigrationTable } from "./data-migration.sql"
|
||||
import * as Log from "@opencode-ai/core/util/log"
|
||||
import { eq } from "drizzle-orm"
|
||||
|
||||
export type Migration<R = never> = {
|
||||
name: string
|
||||
run: Effect.Effect<void, unknown, R>
|
||||
}
|
||||
|
||||
const log = Log.create({ service: "data-migration" })
|
||||
|
||||
export interface Interface {}
|
||||
|
||||
export class Service extends Context.Service<Service, Interface>()("@opencode/DataMigration") {}
|
||||
|
||||
export const layer = Layer.effect(
|
||||
Service,
|
||||
Effect.gen(function* () {
|
||||
const migrations: Migration[] = []
|
||||
|
||||
yield* Effect.gen(function* () {
|
||||
if (migrations.length === 0) return
|
||||
|
||||
// Migrations run in a background fiber, so they must be resumable until
|
||||
// their completion row is written.
|
||||
for (const migration of migrations) {
|
||||
const completed = Database.use((db) =>
|
||||
db
|
||||
.select({ name: DataMigrationTable.name })
|
||||
.from(DataMigrationTable)
|
||||
.where(eq(DataMigrationTable.name, migration.name))
|
||||
.get(),
|
||||
)
|
||||
if (completed) continue
|
||||
|
||||
log.info("running data migration", { name: migration.name })
|
||||
yield* migration.run
|
||||
Database.use((db) =>
|
||||
db
|
||||
.insert(DataMigrationTable)
|
||||
.values({ name: migration.name, time_completed: Date.now() })
|
||||
.onConflictDoNothing()
|
||||
.run(),
|
||||
)
|
||||
}
|
||||
}).pipe(
|
||||
Effect.tapCause((cause) => Effect.logError("failed to run data migrations", { cause })),
|
||||
Effect.ignore,
|
||||
Effect.forkScoped,
|
||||
)
|
||||
return Service.of({})
|
||||
}),
|
||||
)
|
||||
|
||||
export const defaultLayer = layer
|
||||
|
||||
export * as DataMigration from "./data-migration"
|
||||
Reference in New Issue
Block a user