Files
triggerdotdev--trigger.dev/apps/webapp/app/services/autoIncrementCounter.server.ts
Chris Arderne c7861be520 chore: activate no-unused-vars and import linters (#4096)
Once this is merged, oxlint is at a pretty sensible baseline.

**Enable `no-unused-vars`, `typescript/consistent-type-imports`, and
`import/no-duplicates` lint rules**

Turns on three previously-disabled oxlint rules across the monorepo and
fixes all violations:

- **`no-unused-vars`** – enabled as an error with standard ignore
patterns: unused function arguments are ignored by default (`args:
"none"`), variables/caught errors/destructured array elements prefixed
with `_` are allowed, and rest siblings are permitted.
- **`typescript/consistent-type-imports`** – enforced as an error; all
type-only imports now use the `import type` syntax.
- **`import/no-duplicates`** – enforced as an error; duplicate import
statements from the same module have been merged.

The remaining commits clean up the violations found across the codebase:
removing unused variables/imports/type aliases, adding `_` prefixes to
intentionally unused bindings, fixing duplicate imports, and converting
value imports to `import type` where appropriate.
2026-07-02 11:37:05 +01:00

87 lines
2.6 KiB
TypeScript

import type { RedisOptions } from "ioredis";
import Redis from "ioredis";
import { defaultReconnectOnError } from "@internal/redis";
import type { PrismaClientOrTransaction, PrismaTransactionOptions } from "~/db.server";
import { Prisma, prisma } from "~/db.server";
import { env } from "~/env.server";
import { singleton } from "~/utils/singleton";
export type AutoIncrementCounterOptions = {
redis: RedisOptions;
};
export class AutoIncrementCounter {
private _redis: Redis;
constructor(private options: AutoIncrementCounterOptions) {
this._redis = new Redis({ reconnectOnError: defaultReconnectOnError, ...options.redis });
}
async incrementInTransaction<T>(
key: string,
callback: (num: number, tx: PrismaClientOrTransaction) => Promise<T>,
backfiller?: (key: string, db: PrismaClientOrTransaction) => Promise<number | undefined>,
client: PrismaClientOrTransaction = prisma,
transactionOptions?: PrismaTransactionOptions
): Promise<T | undefined> {
let performedIncrement = false;
let performedBackfill = false;
try {
let newNumber = await this.#increment(key);
performedIncrement = true;
if (newNumber === 1 && backfiller) {
const backfilledNumber = await backfiller(key, client);
if (backfilledNumber && backfilledNumber > 1) {
newNumber = backfilledNumber + 1;
await this._redis.set(key, newNumber);
performedBackfill = true;
}
}
return await callback(newNumber, client);
} catch (e) {
if (
e instanceof Prisma.PrismaClientKnownRequestError ||
e instanceof Prisma.PrismaClientUnknownRequestError ||
e instanceof Prisma.PrismaClientValidationError
) {
if (performedIncrement && !performedBackfill) {
await this._redis.decr(key);
}
}
throw e;
}
}
async #increment(key: string): Promise<number> {
return await this._redis.incr(key);
}
}
export const autoIncrementCounter = singleton("auto-increment-counter", getAutoIncrementCounter);
function getAutoIncrementCounter() {
if (!env.REDIS_HOST || !env.REDIS_PORT) {
throw new Error(
"Could not initialize auto-increment counter because process.env.REDIS_HOST and process.env.REDIS_PORT are required to be set. "
);
}
return new AutoIncrementCounter({
redis: {
keyPrefix: "auto-counter:",
port: env.REDIS_PORT,
host: env.REDIS_HOST,
username: env.REDIS_USERNAME,
password: env.REDIS_PASSWORD,
enableAutoPipelining: true,
...(env.REDIS_TLS_DISABLED === "true" ? {} : { tls: {} }),
},
});
}