SiteAdminHandler.js 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. const logger = require('@overleaf/logger')
  2. const settings = require('@overleaf/settings')
  3. const fs = require('fs')
  4. const {
  5. addOptionalCleanupHandlerAfterDrainingConnections,
  6. } = require('./GracefulShutdown')
  7. // Monitor a site maintenance file (e.g. /etc/site_status) periodically and
  8. // close the site if the file contents contain the string "closed".
  9. const STATUS_FILE_CHECK_INTERVAL = 5000
  10. const statusFile = settings.siteMaintenanceFile
  11. function updateSiteMaintenanceStatus(fileContent) {
  12. const isClosed = !settings.siteIsOpen
  13. const shouldBeClosed = fileContent && fileContent.indexOf('closed') >= 0
  14. if (!isClosed && shouldBeClosed) {
  15. settings.siteIsOpen = false
  16. logger.warn({ fileContent }, 'putting site into maintenance mode')
  17. } else if (isClosed && !shouldBeClosed) {
  18. settings.siteIsOpen = true
  19. logger.warn({ fileContent }, 'taking site out of maintenance mode')
  20. }
  21. }
  22. function pollSiteMaintenanceFile() {
  23. fs.readFile(statusFile, { encoding: 'utf8' }, (err, fileContent) => {
  24. if (err) {
  25. logger.error(
  26. { file: statusFile, fsErr: err },
  27. 'error reading site maintenance file'
  28. )
  29. return
  30. }
  31. updateSiteMaintenanceStatus(fileContent)
  32. })
  33. }
  34. function checkSiteMaintenanceFileSync() {
  35. // crash on start up if file does not exist
  36. const content = fs.readFileSync(statusFile, { encoding: 'utf8' })
  37. updateSiteMaintenanceStatus(content)
  38. }
  39. module.exports = {
  40. initialise() {
  41. if (settings.enabledServices.includes('web') && statusFile) {
  42. logger.debug(
  43. { statusFile, interval: STATUS_FILE_CHECK_INTERVAL },
  44. 'monitoring site maintenance file'
  45. )
  46. checkSiteMaintenanceFileSync() // perform an initial synchronous check at start up
  47. const intervalHandle = setInterval(
  48. pollSiteMaintenanceFile,
  49. STATUS_FILE_CHECK_INTERVAL
  50. ) // continue checking periodically
  51. addOptionalCleanupHandlerAfterDrainingConnections(
  52. 'poll site maintenance file',
  53. () => {
  54. clearInterval(intervalHandle)
  55. }
  56. )
  57. }
  58. },
  59. }