mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
115 lines
2.5 KiB
JavaScript
115 lines
2.5 KiB
JavaScript
const logger = require('logger-sharelatex')
|
|
const Settings = require('settings-sharelatex')
|
|
const fs = require('fs')
|
|
const Path = require('path')
|
|
const { promisify } = require('util')
|
|
const disrequire = require('disrequire')
|
|
const rp = require('request-promise-native').defaults({
|
|
resolveWithFullResponse: true
|
|
})
|
|
|
|
const S3_TRIES = 30
|
|
|
|
logger.logger.level('info')
|
|
|
|
const fsReaddir = promisify(fs.readdir)
|
|
const sleep = promisify(setTimeout)
|
|
|
|
class FilestoreApp {
|
|
constructor() {
|
|
this.running = false
|
|
this.initing = false
|
|
}
|
|
|
|
async runServer() {
|
|
if (this.running) {
|
|
return
|
|
}
|
|
|
|
if (this.initing) {
|
|
return this.waitForInit()
|
|
}
|
|
this.initing = true
|
|
|
|
this.app = await FilestoreApp.requireApp()
|
|
|
|
await new Promise((resolve, reject) => {
|
|
this.server = this.app.listen(
|
|
Settings.internal.filestore.port,
|
|
'localhost',
|
|
err => {
|
|
if (err) {
|
|
return reject(err)
|
|
}
|
|
resolve()
|
|
}
|
|
)
|
|
this.app.exceptionHandler.server = this.server
|
|
})
|
|
|
|
if (Settings.filestore.backend === 's3') {
|
|
try {
|
|
await FilestoreApp.waitForS3()
|
|
} catch (err) {
|
|
await this.stop()
|
|
throw err
|
|
}
|
|
}
|
|
|
|
this.initing = false
|
|
}
|
|
|
|
async waitForInit() {
|
|
while (this.initing) {
|
|
await sleep(1000)
|
|
}
|
|
}
|
|
|
|
async stop() {
|
|
const closeServer = promisify(this.server.close).bind(this.server)
|
|
try {
|
|
await closeServer()
|
|
} finally {
|
|
delete this.server
|
|
}
|
|
}
|
|
|
|
static async waitForS3() {
|
|
let tries = 0
|
|
if (!Settings.filestore.s3.endpoint) {
|
|
return
|
|
}
|
|
|
|
let s3Available = false
|
|
|
|
while (tries < S3_TRIES && !s3Available) {
|
|
try {
|
|
const response = await rp.get(`${Settings.filestore.s3.endpoint}/`)
|
|
if ([200, 404].includes(response.statusCode)) {
|
|
s3Available = true
|
|
}
|
|
} catch (err) {
|
|
// swallow errors, as we may experience them until fake-s3 is running
|
|
} finally {
|
|
tries++
|
|
if (!s3Available) {
|
|
await sleep(1000)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static async requireApp() {
|
|
// unload the app, as we may be doing this on multiple runs with
|
|
// different settings, which affect startup in some cases
|
|
const files = await fsReaddir(Path.resolve(__dirname, '../../../app/js'))
|
|
files.forEach(file => {
|
|
disrequire(Path.resolve(__dirname, '../../../app/js', file))
|
|
})
|
|
disrequire(Path.resolve(__dirname, '../../../app'))
|
|
|
|
return require('../../../app')
|
|
}
|
|
}
|
|
|
|
module.exports = FilestoreApp
|