From 67ce7c3c751e7b7ee3ad6b46b4ac5b03fc686a7f Mon Sep 17 00:00:00 2001 From: Tim Alby Date: Fri, 7 Jan 2022 15:30:29 +0100 Subject: [PATCH] asyncify MessageHttpController GitOrigin-RevId: 678a22807f1cbb51a8c1c9bd11b34e1c045d9361 --- .../Messages/MessageHttpController.js | 201 ++++++------------ .../js/Features/Messages/MessageManager.js | 13 +- .../app/js/Features/Threads/ThreadManager.js | 11 +- services/chat/app/js/util/promises.js | 12 ++ 4 files changed, 87 insertions(+), 150 deletions(-) create mode 100644 services/chat/app/js/util/promises.js diff --git a/services/chat/app/js/Features/Messages/MessageHttpController.js b/services/chat/app/js/Features/Messages/MessageHttpController.js index 7f23b71f3c..25ef35b0ff 100644 --- a/services/chat/app/js/Features/Messages/MessageHttpController.js +++ b/services/chat/app/js/Features/Messages/MessageHttpController.js @@ -3,123 +3,74 @@ const MessageManager = require('./MessageManager') const MessageFormatter = require('./MessageFormatter') const ThreadManager = require('../Threads/ThreadManager') const { ObjectId } = require('../../mongodb') +const { expressify } = require('../../util/promises') const DEFAULT_MESSAGE_LIMIT = 50 const MAX_MESSAGE_LENGTH = 10 * 1024 // 10kb, about 1,500 words -function getGlobalMessages(req, res, next) { - _getMessages(ThreadManager.GLOBAL_THREAD, req, res, next) +async function getGlobalMessages(req, res) { + await _getMessages(ThreadManager.GLOBAL_THREAD, req, res) } -function sendGlobalMessage(req, res, next) { - _sendMessage(ThreadManager.GLOBAL_THREAD, req, res, next) +async function sendGlobalMessage(req, res) { + await _sendMessage(ThreadManager.GLOBAL_THREAD, req, res) } -function sendThreadMessage(req, res, next) { - _sendMessage(req.params.threadId, req, res, next) +async function sendThreadMessage(req, res) { + await _sendMessage(req.params.threadId, req, res) } -function getAllThreads(req, res, next) { +async function getAllThreads(req, res) { const { projectId } = req.params logger.log({ projectId }, 'getting all threads') - ThreadManager.findAllThreadRooms(projectId, function (error, rooms) { - if (error) { - return next(error) - } - const roomIds = rooms.map(r => r._id) - MessageManager.findAllMessagesInRooms(roomIds, function (error, messages) { - if (error) { - return next(error) - } - const threads = MessageFormatter.groupMessagesByThreads(rooms, messages) - res.json(threads) - }) - }) + const rooms = await ThreadManager.findAllThreadRooms(projectId) + const roomIds = rooms.map(r => r._id) + const messages = await MessageManager.findAllMessagesInRooms(roomIds) + const threads = MessageFormatter.groupMessagesByThreads(rooms, messages) + res.json(threads) } -function resolveThread(req, res, next) { +async function resolveThread(req, res) { const { projectId, threadId } = req.params const { user_id: userId } = req.body logger.log({ userId, projectId, threadId }, 'marking thread as resolved') - ThreadManager.resolveThread(projectId, threadId, userId, function (error) { - if (error) { - return next(error) - } - res.sendStatus(204) - }) + await ThreadManager.resolveThread(projectId, threadId, userId) + res.sendStatus(204) } -function reopenThread(req, res, next) { +async function reopenThread(req, res) { const { projectId, threadId } = req.params logger.log({ projectId, threadId }, 'reopening thread') - ThreadManager.reopenThread(projectId, threadId, function (error) { - if (error) { - return next(error) - } - res.sendStatus(204) - }) + await ThreadManager.reopenThread(projectId, threadId) + res.sendStatus(204) } -function deleteThread(req, res, next) { +async function deleteThread(req, res) { const { projectId, threadId } = req.params logger.log({ projectId, threadId }, 'deleting thread') - ThreadManager.deleteThread(projectId, threadId, function (error, roomId) { - if (error) { - return next(error) - } - MessageManager.deleteAllMessagesInRoom(roomId, function (error) { - if (error) { - return next(error) - } - res.sendStatus(204) - }) - }) + const roomId = await ThreadManager.deleteThread(projectId, threadId) + await MessageManager.deleteAllMessagesInRoom(roomId) + res.sendStatus(204) } -function editMessage(req, res, next) { +async function editMessage(req, res) { const { content } = req.body const { projectId, threadId, messageId } = req.params logger.log({ projectId, threadId, messageId, content }, 'editing message') - ThreadManager.findOrCreateThread(projectId, threadId, function (error, room) { - if (error) { - return next(error) - } - MessageManager.updateMessage( - room._id, - messageId, - content, - Date.now(), - function (error) { - if (error) { - return next(error) - } - res.sendStatus(204) - } - ) - }) + const room = await ThreadManager.findOrCreateThread(projectId, threadId) + await MessageManager.updateMessage(room._id, messageId, content, Date.now()) + res.sendStatus(204) } -function deleteMessage(req, res, next) { +async function deleteMessage(req, res) { const { projectId, threadId, messageId } = req.params logger.log({ projectId, threadId, messageId }, 'deleting message') - ThreadManager.findOrCreateThread(projectId, threadId, function (error, room) { - if (error) { - return next(error) - } - MessageManager.deleteMessage( - room._id, - messageId, - function (error, message) { - if (error) { - return next(error) - } - res.sendStatus(204) - } - ) - }) + const room = await ThreadManager.findOrCreateThread(projectId, threadId) + await MessageManager.deleteMessage(room._id, messageId) + res.sendStatus(204) } -function _sendMessage(clientThreadId, req, res, next) { +async function _sendMessage(clientThreadId, req, res) { const { user_id: userId, content } = req.body const { projectId } = req.params if (!ObjectId.isValid(userId)) { @@ -137,32 +88,22 @@ function _sendMessage(clientThreadId, req, res, next) { { clientThreadId, projectId, userId, content }, 'new message received' ) - ThreadManager.findOrCreateThread( + const thread = await ThreadManager.findOrCreateThread( projectId, - clientThreadId, - function (error, thread) { - if (error) { - return next(error) - } - MessageManager.createMessage( - thread._id, - userId, - content, - Date.now(), - function (error, message) { - if (error) { - return next(error) - } - message = MessageFormatter.formatMessageForClientSide(message) - message.room_id = projectId - res.status(201).send(message) - } - ) - } + clientThreadId ) + let message = await MessageManager.createMessage( + thread._id, + userId, + content, + Date.now() + ) + message = MessageFormatter.formatMessageForClientSide(message) + message.room_id = projectId + res.status(201).send(message) } -function _getMessages(clientThreadId, req, res, next) { +async function _getMessages(clientThreadId, req, res) { let before, limit const { projectId } = req.params if (req.query.before) { @@ -179,43 +120,29 @@ function _getMessages(clientThreadId, req, res, next) { { limit, before, projectId, clientThreadId }, 'get message request received' ) - ThreadManager.findOrCreateThread( + const thread = await ThreadManager.findOrCreateThread( projectId, - clientThreadId, - function (error, thread) { - if (error) { - return next(error) - } - const threadObjectId = thread._id - logger.log( - { limit, before, projectId, clientThreadId, threadObjectId }, - 'found or created thread' - ) - MessageManager.getMessages( - threadObjectId, - limit, - before, - function (error, messages) { - if (error) { - return next(error) - } - messages = MessageFormatter.formatMessagesForClientSide(messages) - logger.log({ projectId, messages }, 'got messages') - res.status(200).send(messages) - } - ) - } + clientThreadId ) + const threadObjectId = thread._id + logger.log( + { limit, before, projectId, clientThreadId, threadObjectId }, + 'found or created thread' + ) + let messages = await MessageManager.getMessages(threadObjectId, limit, before) + messages = MessageFormatter.formatMessagesForClientSide(messages) + logger.log({ projectId, messages }, 'got messages') + res.status(200).send(messages) } module.exports = { - getGlobalMessages, - sendGlobalMessage, - sendThreadMessage, - getAllThreads, - resolveThread, - reopenThread, - deleteThread, - editMessage, - deleteMessage, + getGlobalMessages: expressify(getGlobalMessages), + sendGlobalMessage: expressify(sendGlobalMessage), + sendThreadMessage: expressify(sendThreadMessage), + getAllThreads: expressify(getAllThreads), + resolveThread: expressify(resolveThread), + reopenThread: expressify(reopenThread), + deleteThread: expressify(deleteThread), + editMessage: expressify(editMessage), + deleteMessage: expressify(deleteMessage), } diff --git a/services/chat/app/js/Features/Messages/MessageManager.js b/services/chat/app/js/Features/Messages/MessageManager.js index 1bd5a60f92..e2dcdc5f71 100644 --- a/services/chat/app/js/Features/Messages/MessageManager.js +++ b/services/chat/app/js/Features/Messages/MessageManager.js @@ -2,7 +2,6 @@ let MessageManager const { db, ObjectId } = require('../../mongodb') const metrics = require('@overleaf/metrics') const logger = require('@overleaf/logger') -const { callbackify } = require('util') async function createMessage(roomId, userId, content, timestamp) { let newMessageOpts = { @@ -75,12 +74,12 @@ function _ensureIdsAreObjectIds(query) { } module.exports = MessageManager = { - createMessage: callbackify(createMessage), - getMessages: callbackify(getMessages), - findAllMessagesInRooms: callbackify(findAllMessagesInRooms), - deleteAllMessagesInRoom: callbackify(deleteAllMessagesInRoom), - updateMessage: callbackify(updateMessage), - deleteMessage: callbackify(deleteMessage), + createMessage, + getMessages, + findAllMessagesInRooms, + deleteAllMessagesInRoom, + updateMessage, + deleteMessage, } ;[ 'createMessage', diff --git a/services/chat/app/js/Features/Threads/ThreadManager.js b/services/chat/app/js/Features/Threads/ThreadManager.js index 19b87c9b4a..1dcdc191e6 100644 --- a/services/chat/app/js/Features/Threads/ThreadManager.js +++ b/services/chat/app/js/Features/Threads/ThreadManager.js @@ -2,7 +2,6 @@ let ThreadManager const { db, ObjectId } = require('../../mongodb') const logger = require('@overleaf/logger') const metrics = require('@overleaf/metrics') -const { callbackify } = require('util') const GLOBAL_THREAD = 'GLOBAL' @@ -96,11 +95,11 @@ async function deleteThread(projectId, threadId) { module.exports = ThreadManager = { GLOBAL_THREAD, - findOrCreateThread: callbackify(findOrCreateThread), - findAllThreadRooms: callbackify(findAllThreadRooms), - resolveThread: callbackify(resolveThread), - reopenThread: callbackify(reopenThread), - deleteThread: callbackify(deleteThread), + findOrCreateThread, + findAllThreadRooms, + resolveThread, + reopenThread, + deleteThread, } ;[ 'findOrCreateThread', diff --git a/services/chat/app/js/util/promises.js b/services/chat/app/js/util/promises.js new file mode 100644 index 0000000000..5a6d88681f --- /dev/null +++ b/services/chat/app/js/util/promises.js @@ -0,0 +1,12 @@ +/** + * Transform an async function into an Express middleware + * + * Any error will be passed to the error middlewares via `next()` + */ +function expressify(fn) { + return (req, res, next) => { + fn(req, res, next).catch(next) + } +} + +module.exports = { expressify }