Skip to content

Commit 611f689

Browse files
committed
fix: Defer initialization of redis
1 parent bef072a commit 611f689

17 files changed

Lines changed: 76 additions & 53 deletions

File tree

packages/openneuro-server/src/app.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import * as jwt from "./libs/authentication/jwt"
2222
import * as auth from "./libs/authentication/states"
2323
import { sitemapHandler } from "./handlers/sitemap"
2424
import { setupPassportAuth } from "./libs/authentication/passport"
25-
import { redis } from "./libs/redis"
25+
import { getRedis } from "./libs/redis"
2626
import { version } from "./lerna.json"
2727
export { Express } from "express-serve-static-core"
2828

@@ -67,7 +67,7 @@ export async function expressApolloSetup() {
6767
// Always allow introspection - our schema is public
6868
introspection: true,
6969
// @ts-expect-error Type mismatch for keyv and ioredis recent releases
70-
cache: new KeyvAdapter(new Keyv({ store: new KeyvRedis(redis) })),
70+
cache: new KeyvAdapter(new Keyv({ store: new KeyvRedis(getRedis()) })),
7171
plugins: [
7272
ApolloServerPluginLandingPageLocalDefault(),
7373
ApolloServerPluginDrainHttpServer({

packages/openneuro-server/src/datalad/__tests__/contributors.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ vi.mock("../../cache/item")
2727
vi.mock("../files")
2828
vi.mock("../../utils/datasetOrSnapshot")
2929
vi.mock("../libs/redis", () => ({
30-
redis: vi.fn(),
30+
getRedis: vi.fn(),
3131
}))
3232

3333
const mockYamlLoad = vi.mocked(yaml.load)

packages/openneuro-server/src/datalad/__tests__/files.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import type { TreeEntry } from "../../cache/tree"
1313

1414
vi.mock("ioredis")
1515
vi.mock("../../config.ts")
16-
vi.mock("../../libs/redis", () => ({ redis: {} }))
16+
vi.mock("../../libs/redis", () => ({ getRedis: () => ({}) }))
1717
vi.mock("../../libs/presign", () => ({
1818
getPresignedUrl: vi.fn().mockResolvedValue(
1919
"https://s3.amazonaws.com/bucket/key?presigned=true",

packages/openneuro-server/src/datalad/__tests__/snapshots.spec.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ import { connect } from "mongoose"
1010
// Mock requests to Datalad service
1111
vi.mock("superagent")
1212
vi.mock("../../libs/redis.js", () => ({
13-
redis: {
13+
getRedis: () => ({
1414
del: vi.fn(),
15-
},
16-
redlock: {
15+
}),
16+
getRedlock: () => ({
1717
lock: vi.fn().mockImplementation(() => ({ unlock: vi.fn() })),
18-
},
18+
}),
1919
}))
2020
// Mock draft files calls
2121
vi.mock("../draft.ts", () => ({

packages/openneuro-server/src/datalad/contributors.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as Sentry from "@sentry/node"
22
import CacheItem, { CacheType } from "../cache/item"
3-
import { redis } from "../libs/redis"
3+
import { getRedis } from "../libs/redis"
44
import {
55
type DatasetOrSnapshot,
66
datasetOrSnapshot,
@@ -26,7 +26,7 @@ export const contributors = async (
2626
if (!datasetId) return []
2727

2828
const revisionShort = revision ? revision.substring(0, 7) : "HEAD"
29-
const dataciteCache = new CacheItem(redis, CacheType.dataciteYml, [
29+
const dataciteCache = new CacheItem(getRedis(), CacheType.dataciteYml, [
3030
datasetId,
3131
revisionShort,
3232
])

packages/openneuro-server/src/datalad/dataset.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import type * as Mongoose from "mongoose"
1212
import config from "../config"
1313
import * as subscriptions from "../handlers/subscriptions"
1414
import { generateDataladCookie } from "../libs/authentication/jwt"
15-
import { redis } from "../libs/redis"
15+
import { getRedis } from "../libs/redis"
1616
import CacheItem, { CacheType } from "../cache/item"
1717
import { getDraftRevision, updateDatasetRevision } from "./draft"
1818
import { encodeFilePath, filesUrl, fileUrl, getFileName } from "./files"
@@ -114,7 +114,7 @@ export const deleteDataset = async (datasetId, user) => {
114114
export const cacheDatasetConnection = (options) => (connectionArguments) => {
115115
const connection = datasetsConnection(options)
116116
const cache = new CacheItem(
117-
redis,
117+
getRedis(),
118118
CacheType.datasetsConnection,
119119
[objectHash(options)],
120120
60,

packages/openneuro-server/src/datalad/description.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
*/
44
import config from "../config"
55
import request from "superagent"
6-
import { redis } from "../libs/redis"
6+
import { getRedis } from "../libs/redis"
77
import { commitFiles } from "./dataset"
88
import { fileUrl } from "./files"
99
import { generateDataladCookie } from "../libs/authentication/jwt"
@@ -135,7 +135,7 @@ export const description = async (obj) => {
135135
Name: datasetId,
136136
BIDSVersion: "1.8.0",
137137
}
138-
const cache = new CacheItem(redis, CacheType.datasetDescription, [
138+
const cache = new CacheItem(getRedis(), CacheType.datasetDescription, [
139139
datasetId,
140140
revision.substring(0, 7),
141141
])

packages/openneuro-server/src/datalad/draft.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import request from "superagent"
55
import Dataset from "../models/dataset"
66
import { getDatasetWorker } from "../libs/datalad-service"
77
import CacheItem, { CacheType } from "../cache/item"
8-
import { redis } from "../libs/redis"
8+
import { getRedis } from "../libs/redis"
99

1010
// Draft info resolver
1111
type DraftInfo = {
@@ -22,7 +22,12 @@ export const getDraftRevision = async (datasetId): Promise<string> => {
2222
}
2323

2424
export const getDraftInfo = async (datasetId) => {
25-
const cache = new CacheItem(redis, CacheType.draftRevision, [datasetId], 10)
25+
const cache = new CacheItem(
26+
getRedis(),
27+
CacheType.draftRevision,
28+
[datasetId],
29+
10,
30+
)
2631
return cache.get(async (_doNotCache): Promise<DraftInfo> => {
2732
const draftUrl = `http://${
2833
getDatasetWorker(

packages/openneuro-server/src/datalad/files.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { redis } from "../libs/redis"
1+
import { getRedis } from "../libs/redis"
22
import { getDatasetWorker } from "../libs/datalad-service"
33
import {
44
getPresignedUrl,
@@ -184,7 +184,7 @@ export async function entryToDatasetFile(
184184
}
185185
let url: string
186186
if (entry.p && entry.k && entry.v) {
187-
url = await getPresignedUrl(redis, entry.b, entry.k, entry.v)
187+
url = await getPresignedUrl(getRedis(), entry.b, entry.k, entry.v)
188188
} else if (entry.k && entry.v) {
189189
url = publicS3Url(entry.b, entry.k, entry.v)
190190
} else {
@@ -260,15 +260,15 @@ async function cacheWorkerTrees(
260260
(f) => f.directory || f.urls[0]?.includes("s3.amazonaws.com"),
261261
)
262262
if (allExported) {
263-
void setTree(redis, hash, entries)
263+
void setTree(getRedis(), hash, entries)
264264
permanentHashes.push(hash)
265265
} else {
266-
void setTree(redis, hash, entries, 600)
266+
void setTree(getRedis(), hash, entries, 600)
267267
}
268268
}
269269
}
270270
if (permanentHashes.length > 0) {
271-
void addDatasetTrees(redis, datasetId, permanentHashes)
271+
void addDatasetTrees(getRedis(), datasetId, permanentHashes)
272272
}
273273
return result
274274
}
@@ -283,7 +283,10 @@ export const resolveGitRef = async (
283283
datasetId: string,
284284
treeish: string,
285285
): Promise<string> => {
286-
const cache = new CacheItem(redis, CacheType.gitRef, [datasetId, treeish])
286+
const cache = new CacheItem(getRedis(), CacheType.gitRef, [
287+
datasetId,
288+
treeish,
289+
])
287290
return cache.get(async () => {
288291
const url = `http://${
289292
getDatasetWorker(datasetId)
@@ -324,7 +327,7 @@ export const getFiles = async (
324327
}
325328
}
326329
// Try cache first
327-
const cached = await getTree(redis, treeish)
330+
const cached = await getTree(getRedis(), treeish)
328331
if (cached) {
329332
return entriesToDatasetFiles(cached, datasetId)
330333
}
@@ -354,10 +357,10 @@ export async function getFilesRecursive(
354357
): Promise<DatasetFile[]> {
355358
const needsPresign = await datasetNeedsPresign(datasetId)
356359
// Check for cached commit-to-trees mapping
357-
const cachedTreeHashes = await getCommitTrees(redis, tree)
360+
const cachedTreeHashes = await getCommitTrees(getRedis(), tree)
358361
if (cachedTreeHashes) {
359362
// Bulk-fetch all trees in one pipeline
360-
const treesMap = await getTreesBulk(redis, cachedTreeHashes)
363+
const treesMap = await getTreesBulk(getRedis(), cachedTreeHashes)
361364
if (treesMap.size < cachedTreeHashes.length) {
362365
// Batch-fetch all missing trees from the worker in one request
363366
const missingHashes = cachedTreeHashes.filter((h) => !treesMap.has(h))
@@ -381,7 +384,7 @@ export async function getFilesRecursive(
381384

382385
while (pendingHashes.length > 0) {
383386
// Check cache for all pending hashes
384-
const cached = await getTreesBulk(redis, pendingHashes)
387+
const cached = await getTreesBulk(getRedis(), pendingHashes)
385388
const uncached = pendingHashes.filter((h) => !cached.has(h))
386389

387390
// Fetch all uncached trees in one worker request
@@ -417,8 +420,8 @@ export async function getFilesRecursive(
417420
// Cache the commit-to-trees mapping for next time
418421
if (collectedHashes.size > 0) {
419422
const hashArray = [...collectedHashes]
420-
void setCommitTrees(redis, tree, hashArray)
421-
void addDatasetTrees(redis, datasetId, hashArray)
423+
void setCommitTrees(getRedis(), tree, hashArray)
424+
void addDatasetTrees(getRedis(), datasetId, hashArray)
422425
}
423426

424427
return reconstructFromTrees(treesMap, tree, path, datasetId)
@@ -485,7 +488,7 @@ async function reconstructFromTrees(
485488
// Bulk-resolve presigned URLs in minimal Redis requests
486489
if (presignIndices.length > 0) {
487490
const urls = await getPresignedUrlsBulk(
488-
redis,
491+
getRedis(),
489492
presignIndices.map((i) => ({
490493
bucket: fileEntries[i].entry.b,
491494
s3Key: fileEntries[i].entry.k,

packages/openneuro-server/src/datalad/readme.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { addFileString, commitFiles } from "./dataset"
2-
import { redis } from "../libs/redis"
2+
import { getRedis } from "../libs/redis"
33
import CacheItem, { CacheType } from "../cache/item"
44
import { getDatasetWorker } from "../libs/datalad-service"
55
import { datasetOrSnapshot } from "../utils/datasetOrSnapshot"
@@ -14,7 +14,7 @@ export const readmeUrl = (datasetId, revision) => {
1414

1515
export const readme = (obj) => {
1616
const { datasetId, revision } = datasetOrSnapshot(obj)
17-
const cache = new CacheItem(redis, CacheType.readme, [
17+
const cache = new CacheItem(getRedis(), CacheType.readme, [
1818
datasetId,
1919
revision.substring(0, 7),
2020
])

0 commit comments

Comments
 (0)