mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-27 01:25:42 -05:00
Added one-minute in-memory server caching for a bunch of common queries.
This commit is contained in:
parent
9b34d4e166
commit
b4e9ee67f0
8 changed files with 51 additions and 39 deletions
|
@ -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
|
||||
|
|
55
package.json
55
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",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.')
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue