From b647d4c1a09f59e54aabd7f492ed3cd591be40e3 Mon Sep 17 00:00:00 2001 From: Chris Brame Date: Tue, 29 Jan 2019 20:55:07 -0500 Subject: [PATCH] fix(socket): high memory usage on notification updates --- src/models/notification.js | 11 ++ src/public/js/angularjs/controllers/common.js | 2 + src/public/js/modules/ui.js | 120 +++++++++--------- src/socketio/notificationSocket.js | 57 +++++++-- 4 files changed, 123 insertions(+), 67 deletions(-) diff --git a/src/models/notification.js b/src/models/notification.js index 25479aa7e..6ae5414ce 100644 --- a/src/models/notification.js +++ b/src/models/notification.js @@ -54,10 +54,21 @@ notificationSchema.statics.findAllForUser = function (oId, callback) { var q = this.model(COLLECTION) .find({ owner: oId }) .sort({ created: -1 }) + .limit(100) return q.exec(callback) } +notificationSchema.statics.getForUserWithLimit = function (oId, callback) { + if (_.isUndefined(oId)) return callback('Invalid ObjectId - NotificationSchema.GetForUserWithLimit()', null) + + return this.model(COLLECTION) + .find({ owner: oId }) + .sort({ created: -1 }) + .limit(5) + .exec(callback) +} + notificationSchema.statics.getCount = function (oId, callback) { if (_.isUndefined(oId)) { return callback('Invalid ObjectId - NotificationSchema.GetCount()', null) diff --git a/src/public/js/angularjs/controllers/common.js b/src/public/js/angularjs/controllers/common.js index 3a290681f..6b7cbf6d4 100644 --- a/src/public/js/angularjs/controllers/common.js +++ b/src/public/js/angularjs/controllers/common.js @@ -361,6 +361,8 @@ define([ $scope.showAllNotificationsWindow = $('#viewAllNotificationsModal') if ($scope.showAllNotificationsWindow.length > 0) { + socket.ui.emitUpdateAllNotifications() + var modal = UI.modal($scope.showAllNotificationsWindow, { bgclose: true }) diff --git a/src/public/js/modules/ui.js b/src/public/js/modules/ui.js index 6d3847e31..f8939c41a 100644 --- a/src/public/js/modules/ui.js +++ b/src/public/js/modules/ui.js @@ -35,6 +35,7 @@ define('modules/ui', [ this.onDisconnect() this.updateUsers() this.updateNotifications() + this.updateAllNotifications() // this.updateMailNotifications(); this.updateConversationsNotifications() this.updateComments() @@ -700,6 +701,10 @@ define('modules/ui', [ e.preventDefault() } + socketUi.emitUpdateAllNotifications = function () { + socket.emit('updateAllNotifications') + } + socketUi.updateComments = function () { socket.removeAllListeners('updateComments') socket.on('updateComments', function (data) { @@ -1117,11 +1122,9 @@ define('modules/ui', [ var $notifications = $('#notifications-Messages').find('ul') if ($notifications.length < 1) return - var last5 = _.take(data.items, 5) - $notifications.html('') // Build Notifications - _.each(last5, function (item) { + _.each(data.items, function (item) { var html = '' html += '
  • ' + @@ -1187,60 +1190,6 @@ define('modules/ui', [ }) }) - // All Notifications - var $notificationsTable = $('table.notificationsTable') - if ($notifications.length > 0) { - var $tbody = $notificationsTable.find('tbody') - $tbody.html('') - _.each(data.items, function (item) { - if (!item.data && item.data.ticket) return - var html = '' - html += - '' - html += '' - html += '' - html += '' - html += '' - html += '

    ' + item.title + '

    ' - html += '
    ' - html += item.message - html += '
    ' - html += '' - html += '' - html += - '' - html += '' - html += '' - - $tbody.append(html) - - var $nRows = $tbody.find('.notification-row') - $.each($nRows, function (k, val) { - var $item = $(val) - $item.off('click') - $item.on('click', function (e) { - e.preventDefault() - e.stopPropagation() - var $id = $(e.currentTarget).attr('data-notificationId') - var $uid = $(e.currentTarget).attr('data-ticket-uid') - socketUi.markNotificationRead($id) - helpers.closeNotificationsWindow() - History.pushState(null, null, '/tickets/' + $uid) - }) - }) - }) - } - var $notificationsCount = $('#btn_notifications').find('span') var $bottomActions = $('#notifications').find('.bottom-actions') if ($notificationsCount.length > 0) { @@ -1257,6 +1206,63 @@ define('modules/ui', [ }) } + socketUi.updateAllNotifications = function () { + socket.removeAllListeners('updateAllNotifications') + socket.on('updateAllNotifications', function (data) { + // All Notifications + var $notificationsTable = $('table.notificationsTable') + var $tbody = $notificationsTable.find('tbody') + $tbody.html('') + _.each(data.items, function (item) { + if (!item.data && item.data.ticket) return + var html = '' + html += + '' + html += '' + html += '' + html += '' + html += '' + html += '

    ' + item.title + '

    ' + html += '
    ' + html += item.message + html += '
    ' + html += '' + html += '' + html += + '' + html += '' + html += '' + + $tbody.append(html) + + var $nRows = $tbody.find('.notification-row') + $.each($nRows, function (k, val) { + var $item = $(val) + $item.off('click') + $item.on('click', function (e) { + e.preventDefault() + e.stopPropagation() + var $id = $(e.currentTarget).attr('data-notificationId') + var $uid = $(e.currentTarget).attr('data-ticket-uid') + socketUi.markNotificationRead($id) + helpers.closeNotificationsWindow() + History.pushState(null, null, '/tickets/' + $uid) + }) + }) + }) + }) + } + socketUi.onTicketCreated = function () { socket.removeAllListeners('ticket:created') socket.on('ticket:created', function () { diff --git a/src/socketio/notificationSocket.js b/src/socketio/notificationSocket.js index 5fa4f70a1..37b46d0fa 100644 --- a/src/socketio/notificationSocket.js +++ b/src/socketio/notificationSocket.js @@ -12,6 +12,7 @@ * Copyright (c) 2014-2019. All rights reserved. */ var _ = require('lodash') +var async = require('async') var winston = require('winston') var utils = require('../helpers/utils') @@ -19,6 +20,7 @@ var events = {} function register (socket) { events.updateNotifications(socket) + events.updateAllNotifications(socket) events.markNotificationRead(socket) events.clearNotifications(socket) } @@ -31,19 +33,48 @@ function updateNotifications () { _.each(io.sockets.sockets, function (socket) { var notifications = {} var notificationSchema = require('../models/notification') - notificationSchema.findAllForUser(socket.request.user._id, function (err, items) { - if (err) { - winston.warn(err) - return true + async.parallel( + [ + function (done) { + notificationSchema.getForUserWithLimit(socket.request.user._id, function (err, items) { + if (err) return done(err) + + notifications.items = items + return done() + }) + }, + function (done) { + notificationSchema.getUnreadCount(socket.request.user._id, function (err, count) { + if (err) return done(err) + + notifications.count = count + return done() + }) + } + ], + function (err) { + if (err) { + winston.warn(err) + return true + } + + utils.sendToSelf(socket, 'updateNotifications', notifications) } + ) + }) +} - // notifications.items = _.take(items, 5); - notifications.items = items - var p = _.filter(items, { unread: true }) - notifications.count = _.size(p) +function updateAllNotifications (socket) { + var notifications = {} + var notificationSchema = require('../models/notification') + notificationSchema.findAllForUser(socket.request.user._id, function (err, items) { + if (err) return false - utils.sendToSelf(socket, 'updateNotifications', notifications) - }) + notifications.items = items + + console.log('Called') + + utils.sendToSelf(socket, 'updateAllNotifications', notifications) }) } @@ -53,6 +84,12 @@ events.updateNotifications = function (socket) { }) } +events.updateAllNotifications = function (socket) { + socket.on('updateAllNotifications', function () { + updateAllNotifications(socket) + }) +} + events.markNotificationRead = function (socket) { socket.on('markNotificationRead', function (_id) { if (_.isUndefined(_id)) return true