From 72a26d35bbd7b5a7b44f9a2bff4c11fced3ee49f Mon Sep 17 00:00:00 2001 From: Tyler Renelle Date: Wed, 28 Aug 2013 17:21:36 -0400 Subject: [PATCH] API: very rudimentary implementation of _v. We'll have a proper implementation in APIv2, but this will help with performance for rewrite & mobile --- assets/js/services/userServices.js | 12 +++++++----- src/controllers/api.coffee | 5 ++++- src/models/user.coffee | 6 +++++- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/assets/js/services/userServices.js b/assets/js/services/userServices.js index f102c83d2a..742bfa3917 100644 --- a/assets/js/services/userServices.js +++ b/assets/js/services/userServices.js @@ -59,17 +59,19 @@ angular.module('userServices', []). sent.push(queue.shift()); }); - $http.post(API_URL + '/api/v1/user/batch-update' + '?date=' + new Date().getTime(), sent) + $http.post(API_URL + '/api/v1/user/batch-update', sent, {params: {data:+new Date, _v:user._v}}) .success(function (data, status, heacreatingders, config) { data.tasks = _.toArray(data.tasks); //make sure there are no pending actions to sync. If there are any it is not safe to apply model from server as we may overwrite user data. if (!queue.length) { //we can't do user=data as it will not update user references in all other angular controllers. - // FIXME - this is the one of the biggest issues in Habit rewrite right now, this function - // kills CPU and makes it things un-responsive. We need to only update the user when it's been - // modified, not every time. Commenting this out makes it out-of-sync with the API though - //_.extend(user, data); + // the user has been modified from another application, sync up + if(data.wasModified) { + delete data.wasModified; + _.extend(user, data); + } + user._v = data._v; // FIXME handle this somewhere else, we don't need to check every single time var offset = moment().zone(); // eg, 240 - this will be converted on server as -(offset/60) diff --git a/src/controllers/api.coffee b/src/controllers/api.coffee index 8178d23f22..231e7e5365 100644 --- a/src/controllers/api.coffee +++ b/src/controllers/api.coffee @@ -34,6 +34,7 @@ api.auth = (req, res, next) -> User.findOne {_id: uid, apiToken: token}, (err, user) -> return res.json(500, {err}) if err return res.json(401, NO_USER_FOUND) if _.isEmpty(user) + res.locals.wasModified = +user._v isnt +req.query._v res.locals.user = user next() @@ -423,6 +424,8 @@ api.batchUpdate = (req, res, next) -> async.series actions, (err) -> res.json = oldJson; res.send = oldSend return res.json(500, {err}) if err - res.json 200, user + response = user.toJSON() + response.wasModified = res.locals.wasModified + res.json 200, response console.log "Reply sent" diff --git a/src/models/user.coffee b/src/models/user.coffee index 7e8759752a..9c90fce605 100644 --- a/src/models/user.coffee +++ b/src/models/user.coffee @@ -6,9 +6,12 @@ _ = require('lodash') UserSchema = new Schema( _id: {type: String, 'default': helpers.uuid} - apiToken: {type: String, 'default': helpers.uuid} + # We want to know *every* time an object updates. Mongoose uses __v to designate when an object contains arrays which + # have been updated (http://goo.gl/gQLz41), but we want *every* update + _v: {type: Number, 'default': 0} + achievements: originalUser: Boolean helpedHabit: Boolean @@ -181,6 +184,7 @@ UserSchema.methods.toJSON = () -> # Custom setter/getter virtuals? UserSchema.pre 'save', (next) -> @markModified('tasks') + @._v++ #our own version incrementer next() module.exports.schema = UserSchema