delete_orphaned_chat_threads.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. const READ_CONCURRENCY_SECONDARY =
  2. parseInt(process.env.READ_CONCURRENCY_SECONDARY, 10) || 1000
  3. const READ_CONCURRENCY_PRIMARY =
  4. parseInt(process.env.READ_CONCURRENCY_PRIMARY, 10) || 500
  5. const WRITE_CONCURRENCY = parseInt(process.env.WRITE_CONCURRENCY, 10) || 10
  6. const BATCH_SIZE = parseInt(process.env.BATCH_SIZE, 10) || 100
  7. const DRY_RUN = process.env.DRY_RUN !== 'false'
  8. const MAX_CHATS_TO_DESTROY =
  9. parseInt(process.env.MAX_CHATS_TO_DESTROY, 10) || false
  10. // persist fallback in order to keep batchedUpdate in-sync
  11. process.env.BATCH_SIZE = BATCH_SIZE
  12. // raise mongo timeout to 10mins if otherwise unspecified
  13. process.env.MONGO_SOCKET_TIMEOUT =
  14. parseInt(process.env.MONGO_SOCKET_TIMEOUT, 10) || 600000
  15. const { ObjectId } = require('mongodb')
  16. const { promiseMapWithLimit } = require('../app/src/util/promises')
  17. const { batchedUpdate } = require('./helpers/batchedUpdate')
  18. const ChatApiHandler = require('../app/src/Features/Chat/ChatApiHandler')
  19. const { getHardDeletedProjectIds } = require('./delete_orphaned_data_helper')
  20. console.log({
  21. DRY_RUN,
  22. WRITE_CONCURRENCY,
  23. BATCH_SIZE,
  24. MAX_CHATS_TO_DESTROY,
  25. })
  26. const RESULT = {
  27. DRY_RUN,
  28. projectChatsDestroyed: 0,
  29. continueFrom: null,
  30. }
  31. async function processBatch(_, rooms) {
  32. if (rooms.length && rooms[0]._id) {
  33. RESULT.continueFrom = rooms[0]._id
  34. }
  35. const projectIds = Array.from(
  36. new Set(rooms.map(room => room.project_id.toString()))
  37. ).map(ObjectId)
  38. console.log(
  39. `Checking projects (${projectIds.length})`,
  40. JSON.stringify(projectIds)
  41. )
  42. const projectsWithOrphanedChat = await getHardDeletedProjectIds({
  43. projectIds,
  44. READ_CONCURRENCY_PRIMARY,
  45. READ_CONCURRENCY_SECONDARY,
  46. })
  47. console.log(
  48. `Destroying chat for projects (${projectsWithOrphanedChat.length})`,
  49. JSON.stringify(projectsWithOrphanedChat)
  50. )
  51. if (!DRY_RUN) {
  52. await promiseMapWithLimit(
  53. WRITE_CONCURRENCY,
  54. projectsWithOrphanedChat,
  55. ChatApiHandler.promises.destroyProject
  56. )
  57. }
  58. RESULT.projectChatsDestroyed += projectsWithOrphanedChat.length
  59. console.log(RESULT)
  60. if (
  61. MAX_CHATS_TO_DESTROY &&
  62. RESULT.projectChatsDestroyed >= MAX_CHATS_TO_DESTROY
  63. ) {
  64. console.log(
  65. `MAX_CHATS_TO_DELETE limit (${MAX_CHATS_TO_DESTROY}) reached. Stopping.`
  66. )
  67. process.exit(0)
  68. }
  69. }
  70. async function main() {
  71. const projection = {
  72. _id: 1,
  73. project_id: 1,
  74. }
  75. await batchedUpdate('rooms', {}, processBatch, projection)
  76. console.log('Final')
  77. console.log(RESULT)
  78. }
  79. main()
  80. .then(() => {
  81. console.log('Done.')
  82. process.exit(0)
  83. })
  84. .catch(error => {
  85. console.error({ error })
  86. process.exit(1)
  87. })