A decentralized music tracking and discovery platform built on AT Protocol 🎵

Abort scrobble publish if lock file exists

Check for a temporary lock file in os.tmpdir() named rocksky-<did>.lock.
If present, log a colored error and exit(1) to avoid concurrent
publishing while the CLI is syncing.

+13
+13
apps/cli/src/scrobble.ts
··· 7 7 import { ctx } from "context"; 8 8 import schema from "schema"; 9 9 import { and, eq, gte, lte } from "drizzle-orm"; 10 + import os from "node:os"; 11 + import path from "node:path"; 12 + import fs from "node:fs"; 13 + import chalk from "chalk"; 10 14 11 15 export async function publishScrobble( 12 16 track: MatchTrackResult, ··· 15 19 const [did, handle] = await getDidAndHandle(); 16 20 const agent: Agent = await createAgent(did, handle); 17 21 const recentScrobble = await getRecentScrobble(did, track, timestamp); 22 + 23 + const lockFilePath = path.join(os.tmpdir(), `rocksky-${did}.lock`); 24 + 25 + if (fs.existsSync(lockFilePath)) { 26 + logger.error( 27 + `${chalk.greenBright(handle)} Scrobble publishing failed: lock file exists, maybe rocksky-cli is still syncing?\nPlease wait for rocksky to finish syncing before publishing scrobbles or delete the lock file manually ${chalk.greenBright(lockFilePath)}`, 28 + ); 29 + process.exit(1); 30 + } 18 31 19 32 if (recentScrobble) { 20 33 logger.info`${handle} Skipping scrobble for ${track.title} by ${track.artist} at ${timestamp ? dayjs.unix(timestamp).format("YYYY-MM-DD HH:mm:ss") : dayjs().format("YYYY-MM-DD HH:mm:ss")} (already scrobbled)`;