Don't call sync functions inside async

Calling sync functions inside async can trigger the node max stack size.
Instead, build up our unique list of ids in advance, so we only call a
method in async for each user we actually need to look up, asynchronously.
Then use all the cached values synchronously afterwards.
This commit is contained in:
James Allen 2017-05-04 17:04:20 +01:00
parent 20433327b8
commit 014e3afb36

View file

@ -34,32 +34,32 @@ module.exports = ChatController =
res.json messages res.json messages
_injectUserInfoIntoThreads: (threads, callback = (error, threads) ->) -> _injectUserInfoIntoThreads: (threads, callback = (error, threads) ->) ->
userCache = {} # There will be a lot of repitition of user_ids, so first build a list
getUserDetails = (user_id, callback = (error, user) ->) -> # of unique ones to perform db look ups on, then use these to populate the
return callback(null, userCache[user_id]) if userCache[user_id]? # user fields
UserInfoManager.getPersonalInfo user_id, (err, user) -> user_ids = {}
return callback(error) if error? for thread_id, thread of threads
user = UserInfoController.formatPersonalInfo user if thread.resolved
userCache[user_id] = user user_ids[thread.resolved_by_user_id] = true
callback null, user for message in thread.messages
user_ids[message.user_id] = true
jobs = [] jobs = []
for thread_id, thread of threads users = {}
do (thread) -> for user_id, _ of user_ids
if thread.resolved do (user_id) ->
jobs.push (cb) -> jobs.push (cb) ->
getUserDetails thread.resolved_by_user_id, (error, user) -> UserInfoManager.getPersonalInfo user_id, (err, user) ->
cb(error) if error? return cb(error) if error?
thread.resolved_by_user = user user = UserInfoController.formatPersonalInfo user
cb() users[user_id] = user
for message in thread.messages cb()
do (message) ->
jobs.push (cb) ->
getUserDetails message.user_id, (error, user) ->
cb(error) if error?
message.user = user
cb()
async.series jobs, (error) -> async.series jobs, (error) ->
return callback(error) if error? return callback(error) if error?
for thread_id, thread of threads
if thread.resolved
thread.resolved_by_user = users[thread.resolved_by_user_id]
for message in thread.messages
message.user = users[message.user_id]
return callback null, threads return callback null, threads