ProjectPersistenceManager.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /* eslint-disable
  2. camelcase,
  3. handle-callback-err,
  4. */
  5. // TODO: This file was created by bulk-decaffeinate.
  6. // Fix any style issues and re-enable lint.
  7. /*
  8. * decaffeinate suggestions:
  9. * DS101: Remove unnecessary use of Array.from
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * DS207: Consider shorter variations of null checks
  12. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  13. */
  14. let ProjectPersistenceManager
  15. const UrlCache = require('./UrlCache')
  16. const CompileManager = require('./CompileManager')
  17. const db = require('./db')
  18. const dbQueue = require('./DbQueue')
  19. const async = require('async')
  20. const logger = require('logger-sharelatex')
  21. const oneDay = 24 * 60 * 60 * 1000
  22. const Settings = require('settings-sharelatex')
  23. const diskusage = require('diskusage')
  24. module.exports = ProjectPersistenceManager = {
  25. EXPIRY_TIMEOUT: Settings.project_cache_length_ms || oneDay * 2.5,
  26. refreshExpiryTimeout(callback) {
  27. if (callback == null) {
  28. callback = function (error) {}
  29. }
  30. diskusage.check('/', function (err, stats) {
  31. if (err) {
  32. logger.err({ err: err }, 'error getting disk usage')
  33. return callback(err)
  34. }
  35. const lowDisk = stats.available / stats.total < 0.1
  36. const lowerExpiry = ProjectPersistenceManager.EXPIRY_TIMEOUT * 0.9
  37. if (lowDisk && Settings.project_cache_length_ms / 2 < lowerExpiry) {
  38. logger.warn(
  39. { stats: stats },
  40. 'disk running low on space, modifying EXPIRY_TIMEOUT'
  41. )
  42. ProjectPersistenceManager.EXPIRY_TIMEOUT = lowerExpiry
  43. }
  44. callback()
  45. })
  46. },
  47. markProjectAsJustAccessed(project_id, callback) {
  48. if (callback == null) {
  49. callback = function (error) {}
  50. }
  51. const job = (cb) =>
  52. db.Project.findOrCreate({ where: { project_id } })
  53. .spread((project, created) =>
  54. project
  55. .update({ lastAccessed: new Date() })
  56. .then(() => cb())
  57. .error(cb)
  58. )
  59. .error(cb)
  60. return dbQueue.queue.push(job, callback)
  61. },
  62. clearExpiredProjects(callback) {
  63. if (callback == null) {
  64. callback = function (error) {}
  65. }
  66. return ProjectPersistenceManager._findExpiredProjectIds(function (
  67. error,
  68. project_ids
  69. ) {
  70. if (error != null) {
  71. return callback(error)
  72. }
  73. logger.log({ project_ids }, 'clearing expired projects')
  74. const jobs = Array.from(project_ids || []).map((project_id) =>
  75. ((project_id) => (callback) =>
  76. ProjectPersistenceManager.clearProjectFromCache(project_id, function (
  77. err
  78. ) {
  79. if (err != null) {
  80. logger.error({ err, project_id }, 'error clearing project')
  81. }
  82. return callback()
  83. }))(project_id)
  84. )
  85. return async.series(jobs, function (error) {
  86. if (error != null) {
  87. return callback(error)
  88. }
  89. return CompileManager.clearExpiredProjects(
  90. ProjectPersistenceManager.EXPIRY_TIMEOUT,
  91. (error) => callback()
  92. )
  93. })
  94. })
  95. }, // ignore any errors from deleting directories
  96. clearProject(project_id, user_id, callback) {
  97. if (callback == null) {
  98. callback = function (error) {}
  99. }
  100. logger.log({ project_id, user_id }, 'clearing project for user')
  101. return CompileManager.clearProject(project_id, user_id, function (error) {
  102. if (error != null) {
  103. return callback(error)
  104. }
  105. return ProjectPersistenceManager.clearProjectFromCache(
  106. project_id,
  107. function (error) {
  108. if (error != null) {
  109. return callback(error)
  110. }
  111. return callback()
  112. }
  113. )
  114. })
  115. },
  116. clearProjectFromCache(project_id, callback) {
  117. if (callback == null) {
  118. callback = function (error) {}
  119. }
  120. logger.log({ project_id }, 'clearing project from cache')
  121. return UrlCache.clearProject(project_id, function (error) {
  122. if (error != null) {
  123. logger.err({ error, project_id }, 'error clearing project from cache')
  124. return callback(error)
  125. }
  126. return ProjectPersistenceManager._clearProjectFromDatabase(
  127. project_id,
  128. function (error) {
  129. if (error != null) {
  130. logger.err(
  131. { error, project_id },
  132. 'error clearing project from database'
  133. )
  134. }
  135. return callback(error)
  136. }
  137. )
  138. })
  139. },
  140. _clearProjectFromDatabase(project_id, callback) {
  141. if (callback == null) {
  142. callback = function (error) {}
  143. }
  144. logger.log({ project_id }, 'clearing project from database')
  145. const job = (cb) =>
  146. db.Project.destroy({ where: { project_id } })
  147. .then(() => cb())
  148. .error(cb)
  149. return dbQueue.queue.push(job, callback)
  150. },
  151. _findExpiredProjectIds(callback) {
  152. if (callback == null) {
  153. callback = function (error, project_ids) {}
  154. }
  155. const job = function (cb) {
  156. const keepProjectsFrom = new Date(
  157. Date.now() - ProjectPersistenceManager.EXPIRY_TIMEOUT
  158. )
  159. const q = {}
  160. q[db.op.lt] = keepProjectsFrom
  161. return db.Project.findAll({ where: { lastAccessed: q } })
  162. .then((projects) =>
  163. cb(
  164. null,
  165. projects.map((project) => project.project_id)
  166. )
  167. )
  168. .error(cb)
  169. }
  170. return dbQueue.queue.push(job, callback)
  171. }
  172. }
  173. logger.log(
  174. { EXPIRY_TIMEOUT: ProjectPersistenceManager.EXPIRY_TIMEOUT },
  175. 'project assets kept timeout'
  176. )