Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 30 additions & 10 deletions packages/opencode/src/storage/storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,10 +82,18 @@ export namespace Storage {
sessionFile,
dest,
})
const session = await Bun.file(sessionFile).json()
const session = await Bun.file(sessionFile)
.json()
.catch((e) => {
log.warn(`Failed to parse session file: ${sessionFile}`, { error: e })
return null
})
if (!session) continue
await Bun.write(dest, JSON.stringify(session))
log.info(`migrating messages for session ${session.id}`)
for await (const msgFile of new Bun.Glob(`storage/session/message/${session.id}/*.json`).scan({
for await (const msgFile of new Bun.Glob(
`storage/session/message/${session.id}/*.json`,
).scan({
cwd: fullProjectDir,
absolute: true,
})) {
Expand All @@ -94,18 +102,30 @@ export namespace Storage {
msgFile,
dest,
})
const message = await Bun.file(msgFile).json()
const message = await Bun.file(msgFile)
.json()
.catch((e) => {
log.warn(`Failed to parse message file: ${msgFile}`, { error: e })
return null
})
if (!message) continue
await Bun.write(dest, JSON.stringify(message))

log.info(`migrating parts for message ${message.id}`)
for await (const partFile of new Bun.Glob(`storage/session/part/${session.id}/${message.id}/*.json`).scan(
{
cwd: fullProjectDir,
absolute: true,
},
)) {
for await (const partFile of new Bun.Glob(
`storage/session/part/${session.id}/${message.id}/*.json`,
).scan({
cwd: fullProjectDir,
absolute: true,
})) {
const dest = path.join(dir, "part", message.id, path.basename(partFile))
const part = await Bun.file(partFile).json()
const part = await Bun.file(partFile)
.json()
.catch((e) => {
log.warn(`Failed to parse part file: ${partFile}`, { error: e })
return null
})
if (!part) continue
log.info("copying", {
partFile,
dest,
Expand Down
35 changes: 34 additions & 1 deletion packages/opencode/src/util/lock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,45 @@ export namespace Lock {
writer: boolean
waitingReaders: (() => void)[]
waitingWriters: (() => void)[]
lastUsed: number
}
>()

const LOCK_TTL = 10 * 1000 // 10 seconds
let cleanupInterval: Timer | null = null

function scheduleCleanup() {
if (cleanupInterval) return
cleanupInterval = setInterval(() => {
const now = Date.now()
for (const [key, lock] of locks.entries()) {
if (
lock.readers === 0 &&
!lock.writer &&
lock.waitingReaders.length === 0 &&
lock.waitingWriters.length === 0 &&
now - lock.lastUsed > LOCK_TTL
) {
locks.delete(key)
}
}
}, 5 * 1000) // cleanup every 5 seconds
cleanupInterval.unref()
}

function get(key: string) {
if (!locks.has(key)) {
scheduleCleanup()
locks.set(key, {
readers: 0,
writer: false,
waitingReaders: [],
waitingWriters: [],
lastUsed: Date.now(),
})
} else {
const lock = locks.get(key)!
lock.lastUsed = Date.now()
}
return locks.get(key)!
}
Expand All @@ -39,7 +67,12 @@ export namespace Lock {
}

// Clean up empty locks
if (lock.readers === 0 && !lock.writer && lock.waitingReaders.length === 0 && lock.waitingWriters.length === 0) {
if (
lock.readers === 0 &&
!lock.writer &&
lock.waitingReaders.length === 0 &&
lock.waitingWriters.length === 0
) {
locks.delete(key)
}
}
Expand Down