fix: stream assets from storage local locations (#2087)

pull/1931/head
Regev Brody 4 years ago committed by GitHub
parent 57f5cbd5b6
commit b2ff064d34
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -6,6 +6,7 @@ const path = require('path')
const fs = require('fs-extra') const fs = require('fs-extra')
const _ = require('lodash') const _ = require('lodash')
const assetHelper = require('../helpers/asset') const assetHelper = require('../helpers/asset')
const Promise = require('bluebird')
/** /**
* Users model * Users model
@ -150,32 +151,53 @@ module.exports = class Asset extends Model {
} }
static async getAsset(assetPath, res) { static async getAsset(assetPath, res) {
let assetExists = await WIKI.models.assets.getAssetFromCache(assetPath, res) try {
if (!assetExists) { const fileHash = assetHelper.generateHash(assetPath)
await WIKI.models.assets.getAssetFromDb(assetPath, res) const cachePath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${fileHash}.dat`)
if (await WIKI.models.assets.getAssetFromCache(assetPath, cachePath, res)) {
return
}
if (await WIKI.models.assets.getAssetFromStorage(assetPath, res)) {
return
}
await WIKI.models.assets.getAssetFromDb(assetPath, fileHash, cachePath, res)
} catch (err) {
if (err.code === `ECONNABORTED` || err.code === `EPIPE`) {
return
}
WIKI.logger.error(err)
res.sendStatus(500)
} }
} }
static async getAssetFromCache(assetPath, res) { static async getAssetFromCache(assetPath, cachePath, res) {
const fileHash = assetHelper.generateHash(assetPath) try {
const cachePath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${fileHash}.dat`) await fs.access(cachePath, fs.constants.R_OK)
} catch (err) {
return new Promise((resolve, reject) => { return false
res.type(path.extname(assetPath)) }
res.sendFile(cachePath, { dotfiles: 'deny' }, err => { const sendFile = Promise.promisify(res.sendFile, {context: res})
if (err) { res.type(path.extname(assetPath))
resolve(false) await sendFile(cachePath, { dotfiles: 'deny' })
} else { return true
resolve(true)
}
})
})
} }
static async getAssetFromDb(assetPath, res) { static async getAssetFromStorage(assetPath, res) {
const fileHash = assetHelper.generateHash(assetPath) const localLocations = await WIKI.models.storage.getLocalLocations({
const cachePath = path.resolve(WIKI.ROOTPATH, WIKI.config.dataPath, `cache/${fileHash}.dat`) asset: {
path: assetPath,
}
})
for (let location of _.filter(localLocations, location => Boolean(location.path))) {
const assetExists = await WIKI.models.assets.getAssetFromCache(assetPath, location.path, res)
if (assetExists) {
return true
}
}
return false
}
static async getAssetFromDb(assetPath, fileHash, cachePath, res) {
const asset = await WIKI.models.assets.query().where('hash', fileHash).first() const asset = await WIKI.models.assets.query().where('hash', fileHash).first()
if (asset) { if (asset) {
const assetData = await WIKI.models.knex('assetData').where('id', asset.id).first() const assetData = await WIKI.models.knex('assetData').where('id', asset.id).first()

@ -199,6 +199,23 @@ module.exports = class Storage extends Model {
} }
} }
static async getLocalLocations({ asset }) {
const locations = []
const promises = this.targets.map(async (target) => {
try {
const path = await target.fn.getLocalLocation(asset)
locations.push({
path,
key: target.key
})
} catch (err) {
WIKI.logger.warn(err)
}
})
await Promise.all(promises)
return locations
}
static async executeAction(targetKey, handler) { static async executeAction(targetKey, handler) {
try { try {
const target = _.find(this.targets, ['key', targetKey]) const target = _.find(this.targets, ['key', targetKey])

@ -114,6 +114,9 @@ module.exports = {
await sourceBlockBlobClient.delete({ await sourceBlockBlobClient.delete({
deleteSnapshots: 'include' deleteSnapshots: 'include'
}) })
},
async getLocalLocation () {
}, },
/** /**
* HANDLERS * HANDLERS

@ -19,5 +19,8 @@ module.exports = {
}, },
async renamed() { async renamed() {
},
async getLocalLocation () {
} }
} }

@ -116,7 +116,9 @@ module.exports = {
WIKI.logger.info(`(STORAGE/DISK) Renaming file from ${asset.path} to ${asset.destinationPath}...`) WIKI.logger.info(`(STORAGE/DISK) Renaming file from ${asset.path} to ${asset.destinationPath}...`)
await fs.move(path.join(this.config.path, asset.path), path.join(this.config.path, asset.destinationPath), { overwrite: true }) await fs.move(path.join(this.config.path, asset.path), path.join(this.config.path, asset.destinationPath), { overwrite: true })
}, },
async getLocalLocation (asset) {
return path.join(this.config.path, asset.path)
},
/** /**
* HANDLERS * HANDLERS
*/ */

@ -19,5 +19,8 @@ module.exports = {
}, },
async renamed() { async renamed() {
},
async getLocalLocation () {
} }
} }

@ -19,5 +19,8 @@ module.exports = {
}, },
async renamed() { async renamed() {
},
async getLocalLocation () {
} }
} }

@ -363,6 +363,9 @@ module.exports = {
'--author': `"${asset.moveAuthorName} <${asset.moveAuthorEmail}>"` '--author': `"${asset.moveAuthorName} <${asset.moveAuthorEmail}>"`
}) })
}, },
async getLocalLocation (asset) {
return path.join(this.repoPath, asset.path)
},
/** /**
* HANDLERS * HANDLERS
*/ */

@ -19,5 +19,8 @@ module.exports = {
}, },
async renamed() { async renamed() {
},
async getLocalLocation () {
} }
} }

@ -119,6 +119,9 @@ module.exports = class S3CompatibleStorage {
WIKI.logger.info(`(STORAGE/${this.storageName}) Renaming file from ${asset.path} to ${asset.destinationPath}...`) WIKI.logger.info(`(STORAGE/${this.storageName}) Renaming file from ${asset.path} to ${asset.destinationPath}...`)
await this.s3.copyObject({ CopySource: asset.path, Key: asset.destinationPath }).promise() await this.s3.copyObject({ CopySource: asset.path, Key: asset.destinationPath }).promise()
await this.s3.deleteObject({ Key: asset.path }).promise() await this.s3.deleteObject({ Key: asset.path }).promise()
}
async getLocalLocation () {
} }
/** /**
* HANDLERS * HANDLERS

@ -103,6 +103,9 @@ module.exports = {
WIKI.logger.info(`(STORAGE/SFTP) Renaming file from ${asset.path} to ${asset.destinationPath}...`) WIKI.logger.info(`(STORAGE/SFTP) Renaming file from ${asset.path} to ${asset.destinationPath}...`)
await this.ensureDirectory(asset.destinationPath) await this.ensureDirectory(asset.destinationPath)
await this.sftp.rename(path.posix.join(this.config.basePath, asset.path), path.posix.join(this.config.basePath, asset.destinationPath)) await this.sftp.rename(path.posix.join(this.config.basePath, asset.path), path.posix.join(this.config.basePath, asset.destinationPath))
},
async getLocalLocation () {
}, },
/** /**
* HANDLERS * HANDLERS

Loading…
Cancel
Save