| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250 |
- diff --git a/services/history-v1/storage/lib/project_key.js b/services/history-v1/storage/lib/project_key.js
- index 03fb2a5141ef..8727576b29f5 100644
- --- a/services/history-v1/storage/lib/project_key.js
- +++ b/services/history-v1/storage/lib/project_key.js
- @@ -1,5 +1,4 @@
- // Keep in sync with services/web/app/src/Features/History/project_key.js
- -const _ = require('lodash')
- const path = require('node:path')
- //
- @@ -13,7 +12,7 @@ function format(projectId) {
- }
- function pad(number) {
- - return _.padStart(number, 9, '0')
- + return (number || 0).toString().padStart(9, '0')
- }
- function naiveReverse(string) {
- diff --git a/services/web/app/src/Features/History/project_key.js b/services/web/app/src/Features/History/project_key.js
- index a4722db09afd..1630bdad0b2b 100644
- --- a/services/web/app/src/Features/History/project_key.js
- +++ b/services/web/app/src/Features/History/project_key.js
- @@ -1,5 +1,4 @@
- // Keep in sync with services/history-v1/storage/lib/project_key.js
- -const _ = require('lodash')
- const path = require('node:path')
- //
- @@ -13,7 +12,7 @@ function format(projectId) {
- }
- function pad(number) {
- - return _.padStart(number, 9, '0')
- + return (number || 0).toString().padStart(9, '0')
- }
- function naiveReverse(string) {
- diff --git a/libraries/object-persistor/src/FSPersistor.js b/libraries/object-persistor/src/FSPersistor.js
- index 38a81407df12..0b5891d2b2ed 100644
- --- a/libraries/object-persistor/src/FSPersistor.js
- +++ b/libraries/object-persistor/src/FSPersistor.js
- @@ -86,7 +86,7 @@ module.exports = class FSPersistor extends AbstractPersistor {
- metric: 'fs.ingress', // ingress to us from disk
- bucket: location,
- })
- - const fsPath = this._getFsPath(location, name)
- + const fsPath = this._getFsPath(location, name, opts.useSubdirectories)
- try {
- opts.fd = await fsPromises.open(fsPath, 'r')
- @@ -295,9 +295,9 @@ module.exports = class FSPersistor extends AbstractPersistor {
- await fsPromises.rm(dirPath, { force: true, recursive: true })
- }
- - _getFsPath(location, key) {
- + _getFsPath(location, key, useSubdirectories = false) {
- key = key.replace(/\/$/, '')
- - if (!this.useSubdirectories) {
- + if (!this.useSubdirectories && !useSubdirectories) {
- key = key.replace(/\//g, '_')
- }
- return Path.join(location, key)
- diff --git a/services/filestore/app.js b/services/filestore/app.js
- index 24741e079c93..e69515ed7de0 100644
- --- a/services/filestore/app.js
- +++ b/services/filestore/app.js
- @@ -119,6 +119,17 @@ app.get(
- fileController.getFile
- )
- +app.get(
- + '/history/global/hash/:hash',
- + keyBuilder.globalBlobFileKeyMiddleware,
- + fileController.getFile
- +)
- +app.get(
- + '/history/project/:historyId/hash/:hash',
- + keyBuilder.projectBlobFileKeyMiddleware,
- + fileController.getFile
- +)
- +
- app.get('/status', function (req, res) {
- if (settings.shuttingDown) {
- res.sendStatus(503) // Service unavailable
- diff --git a/services/filestore/app/js/FileController.js b/services/filestore/app/js/FileController.js
- index 127bbcc20f83..2f77bd015da9 100644
- --- a/services/filestore/app/js/FileController.js
- +++ b/services/filestore/app/js/FileController.js
- @@ -25,6 +25,7 @@ function getFile(req, res, next) {
- format,
- style,
- }
- + if (req.useSubdirectories) options.useSubdirectories = true
- metrics.inc('getFile')
- req.requestLogger.setMessage('getting file')
- diff --git a/services/filestore/app/js/KeyBuilder.js b/services/filestore/app/js/KeyBuilder.js
- index f67a0e81d7ef..66c738171033 100644
- --- a/services/filestore/app/js/KeyBuilder.js
- +++ b/services/filestore/app/js/KeyBuilder.js
- @@ -1,4 +1,5 @@
- const settings = require('@overleaf/settings')
- +const projectKey = require('./project_key')
- module.exports = {
- getConvertedFolderKey,
- @@ -6,6 +7,8 @@ module.exports = {
- userFileKeyMiddleware,
- userProjectKeyMiddleware,
- bucketFileKeyMiddleware,
- + globalBlobFileKeyMiddleware,
- + projectBlobFileKeyMiddleware,
- templateFileKeyMiddleware,
- }
- @@ -50,6 +53,22 @@ function bucketFileKeyMiddleware(req, res, next) {
- next()
- }
- +function globalBlobFileKeyMiddleware(req, res, next) {
- + req.bucket = settings.filestore.stores.global_blobs
- + const { hash } = req.params
- + req.key = `${hash.slice(0, 2)}/${hash.slice(2, 4)}/${hash.slice(4)}`
- + req.useSubdirectories = true
- + next()
- +}
- +
- +function projectBlobFileKeyMiddleware(req, res, next) {
- + req.bucket = settings.filestore.stores.project_blobs
- + const { historyId, hash } = req.params
- + req.key = `${projectKey.format(historyId)}/${hash.slice(0, 2)}/${hash.slice(2)}`
- + req.useSubdirectories = true
- + next()
- +}
- +
- function templateFileKeyMiddleware(req, res, next) {
- const {
- template_id: templateId,
- diff --git a/services/web/app/src/Features/History/project_key.js b/services/filestore/app/js/project_key.js
- similarity index 100%
- rename from services/web/app/src/Features/History/project_key.js
- rename to services/filestore/app/js/project_key.js
- diff --git a/services/history-v1/storage/lib/project_key.js b/services/history-v1/storage/lib/project_key.js
- index 8727576b29f5..6ad239dd12cb 100644
- --- a/services/history-v1/storage/lib/project_key.js
- +++ b/services/history-v1/storage/lib/project_key.js
- @@ -1,4 +1,4 @@
- -// Keep in sync with services/web/app/src/Features/History/project_key.js
- +// Keep in sync with services/filestore/app/js/project_key.js
- const path = require('node:path')
- //
- diff --git a/services/web/app/src/Features/Compile/ClsiManager.js b/services/web/app/src/Features/Compile/ClsiManager.js
- index 6f11297248ee..19370684dd80 100644
- --- a/services/web/app/src/Features/Compile/ClsiManager.js
- +++ b/services/web/app/src/Features/Compile/ClsiManager.js
- @@ -26,7 +26,7 @@ const DocumentUpdaterHandler = require('../DocumentUpdater/DocumentUpdaterHandle
- const Metrics = require('@overleaf/metrics')
- const Errors = require('../Errors/Errors')
- const ClsiCacheHandler = require('./ClsiCacheHandler')
- -const { getBlobLocation } = require('../History/HistoryManager')
- +const { getFilestoreBlobURL } = require('../History/HistoryManager')
- const VALID_COMPILERS = ['pdflatex', 'latex', 'xelatex', 'lualatex']
- const OUTPUT_FILE_TIMEOUT_MS = 60000
- @@ -755,8 +755,7 @@ function _finaliseRequest(projectId, options, project, docs, files) {
- let url = filestoreURL
- let fallbackURL
- if (file.hash && Features.hasFeature('project-history-blobs')) {
- - const { bucket, key } = getBlobLocation(historyId, file.hash)
- - url = `${Settings.apis.filestore.url}/bucket/${bucket}/key/${key}`
- + url = getFilestoreBlobURL(historyId, file.hash)
- fallbackURL = filestoreURL
- }
- resources.push({
- diff --git a/services/web/app/src/Features/History/HistoryManager.js b/services/web/app/src/Features/History/HistoryManager.js
- index 42d7e229bf97..a2fb201399d1 100644
- --- a/services/web/app/src/Features/History/HistoryManager.js
- +++ b/services/web/app/src/Features/History/HistoryManager.js
- @@ -15,11 +15,6 @@ const { db, ObjectId, waitForDb } = require('../../infrastructure/mongodb')
- const Metrics = require('@overleaf/metrics')
- const logger = require('@overleaf/logger')
- const { NotFoundError } = require('../Errors/Errors')
- -const projectKey = require('./project_key')
- -
- -// BEGIN copy from services/history-v1/storage/lib/blob_store/index.js
- -
- -const GLOBAL_BLOBS = new Set() // CHANGE FROM SOURCE: only store hashes.
- const HISTORY_V1_URL = settings.apis.v1_history.url
- const HISTORY_V1_BASIC_AUTH = {
- @@ -27,27 +22,9 @@ const HISTORY_V1_BASIC_AUTH = {
- password: settings.apis.v1_history.pass,
- }
- -function makeGlobalKey(hash) {
- - return `${hash.slice(0, 2)}/${hash.slice(2, 4)}/${hash.slice(4)}`
- -}
- -
- -function makeProjectKey(projectId, hash) {
- - return `${projectKey.format(projectId)}/${hash.slice(0, 2)}/${hash.slice(2)}`
- -}
- +// BEGIN copy from services/history-v1/storage/lib/blob_store/index.js
- -function getBlobLocation(projectId, hash) {
- - if (GLOBAL_BLOBS.has(hash)) {
- - return {
- - bucket: settings.apis.v1_history.buckets.globalBlobs,
- - key: makeGlobalKey(hash),
- - }
- - } else {
- - return {
- - bucket: settings.apis.v1_history.buckets.projectBlobs,
- - key: makeProjectKey(projectId, hash),
- - }
- - }
- -}
- +const GLOBAL_BLOBS = new Set() // CHANGE FROM SOURCE: only store hashes.
- async function loadGlobalBlobs() {
- await waitForDb() // CHANGE FROM SOURCE: wait for db before running query.
- @@ -59,6 +36,14 @@ async function loadGlobalBlobs() {
- // END copy from services/history-v1/storage/lib/blob_store/index.js
- +function getFilestoreBlobURL(historyId, hash) {
- + if (GLOBAL_BLOBS.has(hash)) {
- + return `${settings.apis.filestore.url}/history/global/hash/${hash}`
- + } else {
- + return `${settings.apis.filestore.url}/history/project/${historyId}/hash/${hash}`
- + }
- +}
- +
- async function initializeProject(projectId) {
- const body = await fetchJson(`${settings.apis.project_history.url}/project`, {
- method: 'POST',
- @@ -421,7 +406,7 @@ function _userView(user) {
- const loadGlobalBlobsPromise = loadGlobalBlobs()
- module.exports = {
- - getBlobLocation,
- + getFilestoreBlobURL,
- loadGlobalBlobsPromise,
- initializeProject: callbackify(initializeProject),
- flushProject: callbackify(flushProject),
|