| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- const logger = require('@overleaf/logger')
- const Settings = require('@overleaf/settings')
- const fs = require('fs')
- const Path = require('path')
- const { promisify } = require('util')
- const disrequire = require('disrequire')
- const AWS = require('aws-sdk')
- 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 await this.waitForInit()
- }
- this.initing = true
- this.app = await FilestoreApp.requireApp()
- await new Promise((resolve, reject) => {
- this.server = this.app.listen(
- Settings.internal.filestore.port,
- '127.0.0.1',
- err => {
- if (err) {
- return reject(err)
- }
- resolve()
- }
- )
- })
- if (Settings.filestore.backend === 's3') {
- try {
- await FilestoreApp.waitForS3()
- } catch (err) {
- await this.stop()
- throw err
- }
- }
- this.initing = false
- this.persistor = require('../../../app/js/PersistorManager')
- }
- async waitForInit() {
- while (this.initing) {
- await sleep(1000)
- }
- }
- async stop() {
- if (!this.server) return
- 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
- }
- const s3 = new AWS.S3({
- accessKeyId: Settings.filestore.s3.key,
- secretAccessKey: Settings.filestore.s3.secret,
- endpoint: Settings.filestore.s3.endpoint,
- s3ForcePathStyle: true,
- signatureVersion: 'v4',
- })
- while (true) {
- try {
- return await s3
- .putObject({
- Key: 'startup',
- Body: '42',
- Bucket: Settings.filestore.stores.user_files,
- })
- .promise()
- } catch (err) {
- // swallow errors, as we may experience them until fake-s3 is running
- if (tries === 9) {
- // throw just before hitting the 10s test timeout
- throw err
- }
- tries++
- 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'))
- disrequire('@overleaf/object-persistor')
- return require('../../../app')
- }
- }
- module.exports = FilestoreApp
|