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
7 changes: 6 additions & 1 deletion src/infrastructure/jobs/redis-job-queue.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@ function getOrCreateRedisConnection(): IORedis {
}

const { host, port, password } = readRedisEnv();
// tls: {} is required for Upstash Redis (TLS-only endpoint, rediss:// scheme).
redisConnectionInstance = new IORedis({
host,
port,
password,
tls: {},
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Make TLS optional for non-Upstash Redis deployments

This change forces tls: {} on all Redis connections (getOrCreateRedisConnection, BullMQ queue connection, createRedisClient, and worker connection options), which turns every connection into TLS-only. The repository still includes a default deploy path that wires REDIS_HOST/REDIS_PORT from Railway RAILWAY_TCP_PROXY_* values (scripts/deploy/railway-provision-and-deploy.sh), so environments that are still plain TCP will regress from working to handshake failures, breaking queue enqueue/worker startup. Gate TLS with an explicit setting (or URL scheme) instead of hardcoding it for all Redis backends.

Useful? React with 👍 / 👎.

maxRetriesPerRequest: null,
retryStrategy: () => null
});
Expand All @@ -58,9 +60,10 @@ async function getQueue(): Promise<Queue> {
// Pass plain options to BullMQ so it uses its own internal ioredis instance.
// Avoids a TypeScript structural type conflict between top-level ioredis and
// the ioredis bundled inside bullmq/node_modules.
// tls: {} is required for Upstash Redis (TLS-only endpoint).
const { host, port, password } = readRedisEnv();
queueInstance = new Queue(JOB_QUEUE_NAME, {
connection: { host, port, password, maxRetriesPerRequest: null },
connection: { host, port, password, tls: {}, maxRetriesPerRequest: null },
defaultJobOptions: {
attempts: DEFAULT_ATTEMPTS,
backoff: { type: "exponential", delay: BACKOFF_DELAY_MS },
Expand Down Expand Up @@ -109,10 +112,12 @@ export function assertRedisJobConfiguration(): void {

export function createRedisClient(): IORedis {
const { host, port, password } = readRedisEnv();
// tls: {} is required for Upstash Redis (TLS-only endpoint).
return new IORedis({
host,
port,
password,
tls: {},
maxRetriesPerRequest: null,
retryStrategy: () => null
});
Expand Down
3 changes: 2 additions & 1 deletion src/infrastructure/jobs/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export async function startJobsWorker(): Promise<void> {
// Pass plain options so BullMQ uses its own internal ioredis instance.
// Avoids a TypeScript structural type conflict between top-level ioredis
// and the ioredis bundled inside bullmq/node_modules.
const connectionOptions = { host, port, password, maxRetriesPerRequest: null as null };
// tls: {} is required for Upstash Redis (TLS-only endpoint).
const connectionOptions = { host, port, password, tls: {}, maxRetriesPerRequest: null as null };

new Worker(
getRedisQueueName(),
Expand Down