diff --git a/app/views/ladder/LadderView.coffee b/app/views/ladder/LadderView.coffee index 02dc9d4f0..bc2873624 100644 --- a/app/views/ladder/LadderView.coffee +++ b/app/views/ladder/LadderView.coffee @@ -64,7 +64,7 @@ module.exports = class LadderView extends RootView @insertSubView(@ladderTab = new LadderTabView({}, @level, @sessions)) @insertSubView(@myMatchesTab = new MyMatchesTabView({}, @level, @sessions)) @insertSubView(@simulateTab = new SimulateTabView()) - @refreshInterval = setInterval(@fetchSessionsAndRefreshViews.bind(@), 20 * 1000) + @refreshInterval = setInterval(@fetchSessionsAndRefreshViews.bind(@), 60 * 1000) hash = document.location.hash[1..] if document.location.hash if hash and not (hash in ['my-matches', 'simulate', 'ladder', 'prizes', 'rules', 'winners']) @showPlayModal(hash) if @sessions.loaded diff --git a/package.json b/package.json index 97cb28cb9..221171e45 100644 --- a/package.json +++ b/package.json @@ -38,36 +38,37 @@ "multiplayer" ], "dependencies": { - "express": "~3.0.6", - "winston": "0.6.x", - "passport": "0.1.x", - "passport-local": "0.1.x", - "moment": "~2.5.0", - "mongoose": "3.8.x", - "request": "2.12.x", - "tv4": "~1.0.16", - "lodash": "~2.4.1", - "underscore.string": "2.3.x", - "async": "0.2.x", - "connect": "2.7.x", - "coffee-script": "1.9.x", - "graceful-fs": "~2.0.1", - "node-force-domain": "~0.1.0", - "mailchimp-api": "2.0.x", - "express-useragent": "~0.0.9", - "gridfs-stream": "0.4.x", - "stream-buffers": "0.2.x", - "sendwithus": "2.1.x", - "aws-sdk": "~2.0.0", - "bayesian-battle": "0.0.x", - "redis": "", - "webworker-threads": "~0.5.5", - "node-gyp": "~0.13.0", - "aether": "~0.3.0", "JASON": "~0.1.3", "JQDeferred": "~2.1.0", + "aether": "~0.3.0", + "async": "0.2.x", + "aws-sdk": "~2.0.0", + "bayesian-battle": "0.0.x", + "coffee-script": "1.9.x", + "connect": "2.7.x", + "express": "~3.0.6", + "express-useragent": "~0.0.9", + "graceful-fs": "~2.0.1", + "gridfs-stream": "0.4.x", "jsondiffpatch": "0.1.17", - "stripe": "~2.9.0" + "lodash": "~2.4.1", + "mailchimp-api": "2.0.x", + "moment": "~2.5.0", + "mongoose": "3.8.x", + "mongoose-cache": "https://github.com/nwinter/mongoose-cache/tarball/master", + "node-force-domain": "~0.1.0", + "node-gyp": "~0.13.0", + "passport": "0.1.x", + "passport-local": "0.1.x", + "redis": "", + "request": "2.12.x", + "sendwithus": "2.1.x", + "stream-buffers": "0.2.x", + "stripe": "~2.9.0", + "tv4": "~1.0.16", + "underscore.string": "2.3.x", + "webworker-threads": "~0.5.5", + "winston": "0.6.x" }, "devDependencies": { "auto-reload-brunch": "> 1.0 < 1.8", diff --git a/server/commons/database.coffee b/server/commons/database.coffee index c47983605..65b06159a 100644 --- a/server/commons/database.coffee +++ b/server/commons/database.coffee @@ -2,6 +2,7 @@ config = require '../../server_config' winston = require 'winston' mongoose = require 'mongoose' Grid = require 'gridfs-stream' +mongooseCache = require 'mongoose-cache' global.testing = testing = '--unittest' in process.argv @@ -13,6 +14,7 @@ module.exports.connect = () -> mongoose.connect address mongoose.connection.once 'open', -> Grid.gfs = Grid(mongoose.connection.db, mongoose.mongo) + mongooseCache.install(mongoose, {max: 200, maxAge: 1 * 60 * 1000, debug: false}) module.exports.generateMongoConnectionString = -> if not testing and config.mongo.mongoose_replica_string diff --git a/server/levels/level_handler.coffee b/server/levels/level_handler.coffee index 5523c75f4..d3060c173 100644 --- a/server/levels/level_handler.coffee +++ b/server/levels/level_handler.coffee @@ -164,6 +164,7 @@ LevelHandler = class LevelHandler extends Handler {$match: {'levelID': slug, 'submitted': true, 'team': req.query.team}} {$project: {totalScore: 1, _id: 0}} ] + #query.cache() # TODO: implement caching for aggregates query.exec (err, data) => if err? then return @sendDatabaseError res, err @@ -199,6 +200,7 @@ LevelHandler = class LevelHandler extends Handler .limit(req.query.limit) .sort(sortParameters) .select(selectProperties.join ' ') + query.cache() if sessionsQueryParameters.totalScore.$lt is 1000000 query.exec (err, resultSessions) => return @sendDatabaseError(res, err) if err @@ -269,6 +271,7 @@ LevelHandler = class LevelHandler extends Handler query = Level.findOne(findParameters) .select(selectString) .lean() + .cache() query.exec (err, level) => return @sendDatabaseError(res, err) if err @@ -280,17 +283,19 @@ LevelHandler = class LevelHandler extends Handler majorVersion: level.version.major submitted: true - query = Session.find(sessionsQueryParameters).distinct('team') + query = Session.find(sessionsQueryParameters).distinct('team').cache() query.exec (err, teams) => return @sendDatabaseError res, err if err? or not teams findTop20Players = (sessionQueryParams, team, cb) -> sessionQueryParams['team'] = team - Session.aggregate [ + aggregate = Session.aggregate [ {$match: sessionQueryParams} {$project: {'totalScore': 1}} {$sort: {'totalScore': -1}} {$limit: 20} - ], cb + ] + #aggregate.cache() # TODO: implement caching for aggregates + aggregate.exec cb async.map teams, findTop20Players.bind(@, sessionsQueryParameters), (err, map) => if err? then return @sendDatabaseError(res, err) diff --git a/server/levels/thangs/thang_type_handler.coffee b/server/levels/thangs/thang_type_handler.coffee index 1e0406793..6ca514c47 100644 --- a/server/levels/thangs/thang_type_handler.coffee +++ b/server/levels/thangs/thang_type_handler.coffee @@ -70,6 +70,8 @@ ThangTypeHandler = class ThangTypeHandler extends Handler if limit? and limit < 1000 q.limit(limit) + q.cache() + q.exec (err, documents) => return @sendDatabaseError(res, err) if err documents = (@formatEntity(req, doc) for doc in documents) diff --git a/server/queues/scoring.coffee b/server/queues/scoring.coffee index 9f1bcd571..0d88564b0 100644 --- a/server/queues/scoring.coffee +++ b/server/queues/scoring.coffee @@ -138,7 +138,7 @@ module.exports.getTwoGames = (req, res) -> 'submitted': true 'team': 'humans' selection = 'team totalScore transpiledCode submittedCodeLanguage teamSpells levelID creatorName creator submitDate' - LevelSession.count queryParams, (err, numberOfHumans) => + LevelSession.count(queryParams).cache().exec (err, numberOfHumans) => if err? then return errors.serverError(res, 'Couldn\'t get the number of human games') unless numberOfHumans res.send(204, 'No games to score.') @@ -149,7 +149,7 @@ module.exports.getTwoGames = (req, res) -> 'levelID': levelID 'submitted': true 'team': 'ogres' - LevelSession.count ogreCountParams, (err, numberOfOgres) => + LevelSession.count(ogreCountParams).cache().exec (err, numberOfOgres) => if err? then return errors.serverError(res, 'Couldn\'t get the number of ogre games') unless numberOfOgres res.send(204, 'No games to score.') diff --git a/server/users/user_handler.coffee b/server/users/user_handler.coffee index b8cc6b6fa..1822e30d2 100644 --- a/server/users/user_handler.coffee +++ b/server/users/user_handler.coffee @@ -172,11 +172,12 @@ UserHandler = class UserHandler extends Handler getSimulatorLeaderboard: (req, res) -> queryParameters = @getSimulatorLeaderboardQueryParameters(req) leaderboardQuery = User.find(queryParameters.query).select('name simulatedBy simulatedFor').sort({'simulatedBy': queryParameters.sortOrder}).limit(queryParameters.limit) + leaderboardQuery.cache() if req.query.scoreOffset is -1 leaderboardQuery.exec (err, otherUsers) -> - otherUsers = _.reject otherUsers, _id: req.user._id if req.query.scoreOffset isnt -1 - otherUsers ?= [] - res.send(otherUsers) - res.end() + otherUsers = _.reject otherUsers, _id: req.user._id if req.query.scoreOffset isnt -1 + otherUsers ?= [] + res.send(otherUsers) + res.end() getMySimulatorLeaderboardRank: (req, res) -> req.query.order = 1 @@ -229,12 +230,12 @@ UserHandler = class UserHandler extends Handler for prop, val of obj user.set(prop, undefined) unless prop is '_id' user.set('deleted', true) - + # Hack to get saving of Users to work. Probably should replace these props with strings # so that validation doesn't get hung up on Date objects in the documents. delete obj.dateCreated - user.save (err) => + user.save (err) => return @sendDatabaseError(res, err) if err @sendNoContent res diff --git a/server_setup.coffee b/server_setup.coffee index ab99f4a04..bcdef1a38 100644 --- a/server_setup.coffee +++ b/server_setup.coffee @@ -53,6 +53,7 @@ setupErrorMiddleware = (app) -> hipchat.sendHipChatMessage(message, ['tower'], {papertrail: true}) else next(err) + setupExpressMiddleware = (app) -> if config.isProduction express.logger.format('prod', productionLogging)