setup memcache
This commit is contained in:
48
backend/package-lock.json
generated
48
backend/package-lock.json
generated
@@ -13,6 +13,7 @@
|
|||||||
"asty-astq": "^1.14.0",
|
"asty-astq": "^1.14.0",
|
||||||
"body-parser": "^1.20.2",
|
"body-parser": "^1.20.2",
|
||||||
"express": "^4.18.3",
|
"express": "^4.18.3",
|
||||||
|
"memcached": "^2.2.2",
|
||||||
"net": "^1.0.2",
|
"net": "^1.0.2",
|
||||||
"pg-hstore": "^2.3.4",
|
"pg-hstore": "^2.3.4",
|
||||||
"sequelize": "^6.37.1",
|
"sequelize": "^6.37.1",
|
||||||
@@ -1918,6 +1919,12 @@
|
|||||||
"safe-buffer": "~5.1.0"
|
"safe-buffer": "~5.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/connection-parse": {
|
||||||
|
"version": "0.0.7",
|
||||||
|
"resolved": "https://registry.npmjs.org/connection-parse/-/connection-parse-0.0.7.tgz",
|
||||||
|
"integrity": "sha512-bTTG28diWg7R7/+qE5NZumwPbCiJOT8uPdZYu674brDjBWQctbaQbYlDKhalS+4i5HxIx+G8dZsnBHKzWpp01A==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/console-browserify": {
|
"node_modules/console-browserify": {
|
||||||
"version": "1.2.0",
|
"version": "1.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz",
|
||||||
@@ -3336,6 +3343,16 @@
|
|||||||
"minimalistic-assert": "^1.0.1"
|
"minimalistic-assert": "^1.0.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/hashring": {
|
||||||
|
"version": "3.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/hashring/-/hashring-3.2.0.tgz",
|
||||||
|
"integrity": "sha512-xCMovURClsQZ+TR30icCZj+34Fq1hs0y6YCASD6ZqdRfYRybb5Iadws2WS+w09mGM/kf9xyA5FCdJQGcgcraSA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"connection-parse": "0.0.x",
|
||||||
|
"simple-lru-cache": "0.0.x"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/hasown": {
|
"node_modules/hasown": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.1.tgz",
|
||||||
@@ -3795,6 +3812,22 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jackpot": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/jackpot/-/jackpot-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-rbWXX+A9ooq03/dfavLg9OXQ8YB57Wa7PY5c4LfU3CgFpwEhhl3WyXTQVurkaT7zBM5I9SSOaiLyJ4I0DQmC0g==",
|
||||||
|
"dependencies": {
|
||||||
|
"retry": "0.6.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/jackpot/node_modules/retry": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/retry/-/retry-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-RgncoxLF1GqwAzTZs/K2YpZkWrdIYbXsmesdomi+iPilSzjUyr/wzNIuteoTVaWokzdwZIJ9NHRNQa/RUiOB2g==",
|
||||||
|
"engines": {
|
||||||
|
"node": "*"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/jest-worker": {
|
"node_modules/jest-worker": {
|
||||||
"version": "27.5.1",
|
"version": "27.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
|
||||||
@@ -4001,6 +4034,16 @@
|
|||||||
"node": ">= 0.6"
|
"node": ">= 0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/memcached": {
|
||||||
|
"version": "2.2.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/memcached/-/memcached-2.2.2.tgz",
|
||||||
|
"integrity": "sha512-lHwUmqkT9WdUUgRsAvquO4xsKXYaBd644Orz31tuth+w/BIfFNuJMWwsG7sa7H3XXytaNfPTZ5R/yOG3d9zJMA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"hashring": "3.2.x",
|
||||||
|
"jackpot": ">=0.0.6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/merge-descriptors": {
|
"node_modules/merge-descriptors": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
|
||||||
@@ -5632,6 +5675,11 @@
|
|||||||
"simple-concat": "^1.0.0"
|
"simple-concat": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/simple-lru-cache": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/simple-lru-cache/-/simple-lru-cache-0.0.2.tgz",
|
||||||
|
"integrity": "sha512-uEv/AFO0ADI7d99OHDmh1QfYzQk/izT1vCmu/riQfh7qjBVUUgRT87E5s5h7CxWCA/+YoZerykpEthzVrW3LIw=="
|
||||||
|
},
|
||||||
"node_modules/slash": {
|
"node_modules/slash": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||||
|
|||||||
@@ -32,6 +32,7 @@
|
|||||||
"asty-astq": "^1.14.0",
|
"asty-astq": "^1.14.0",
|
||||||
"body-parser": "^1.20.2",
|
"body-parser": "^1.20.2",
|
||||||
"express": "^4.18.3",
|
"express": "^4.18.3",
|
||||||
|
"memcached": "^2.2.2",
|
||||||
"net": "^1.0.2",
|
"net": "^1.0.2",
|
||||||
"pg-hstore": "^2.3.4",
|
"pg-hstore": "^2.3.4",
|
||||||
"sequelize": "^6.37.1",
|
"sequelize": "^6.37.1",
|
||||||
|
|||||||
@@ -7,15 +7,20 @@ import { addGameApis } from './gameservice'
|
|||||||
import { addCharacterApis } from './characterservice'
|
import { addCharacterApis } from './characterservice'
|
||||||
import { addRushStatsApis } from './rushstatsservice'
|
import { addRushStatsApis } from './rushstatsservice'
|
||||||
import { addDmApis } from './dmservice'
|
import { addDmApis } from './dmservice'
|
||||||
|
import { Memcache } from './memcache'
|
||||||
|
|
||||||
|
var Memcached = require('memcached')
|
||||||
|
|
||||||
const app = express()
|
const app = express()
|
||||||
const jsonParser = json()
|
const jsonParser = json()
|
||||||
const port = 3001
|
const port = 3001
|
||||||
|
// const memcache = new memcached('localhost:11211', {})
|
||||||
|
const memcachep = new Memcache('localhost:11211')
|
||||||
|
|
||||||
addGameApis(app, jsonParser)
|
addGameApis(app, jsonParser, memcachep)
|
||||||
addCharacterApis(app, jsonParser)
|
addCharacterApis(app, jsonParser, memcachep)
|
||||||
addRushStatsApis(app, jsonParser)
|
addRushStatsApis(app, jsonParser, memcachep)
|
||||||
addDmApis(app, jsonParser)
|
addDmApis(app, jsonParser, memcachep)
|
||||||
|
|
||||||
app.use(express.static(__dirname + '/frontend'))
|
app.use(express.static(__dirname + '/frontend'))
|
||||||
app.use('/', (req, res) => {
|
app.use('/', (req, res) => {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { database, Character, Game, Pick, App } from './db'
|
import { database, Character, Game, Pick, App } from './db'
|
||||||
import { OrderByParser, FilterParser, ParsingError } from './tokenizer'
|
import { OrderByParser, FilterParser, ParsingError } from './tokenizer'
|
||||||
|
|
||||||
export function addCharacterApis(app, jsonParser) {
|
export function addCharacterApis(app, jsonParser, memcace) {
|
||||||
app.get('/api/character/:characterId', async (req, res) => {
|
app.get('/api/character/:characterId', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const character = await Character.findOne({
|
const character = await Character.findOne({
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { database, Character, Game, Pick, App } from './db'
|
|||||||
import { OrderByParser, FilterParser, ParsingError } from './tokenizer'
|
import { OrderByParser, FilterParser, ParsingError } from './tokenizer'
|
||||||
import { fn, col } from 'sequelize'
|
import { fn, col } from 'sequelize'
|
||||||
|
|
||||||
export function addDmApis(app, jsonParser) {
|
export function addDmApis(app, jsonParser, memcache) {
|
||||||
app.get('/api/dm/:dmName', async (req, res) => {
|
app.get('/api/dm/:dmName', async (req, res) => {
|
||||||
const dmName = req.params.dmName
|
const dmName = req.params.dmName
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { database, Character, Game, Pick, App } from './db'
|
import { database, Character, Game, Pick, App } from './db'
|
||||||
import { OrderByParser, FilterParser, ParsingError } from './tokenizer'
|
import { OrderByParser, FilterParser, ParsingError } from './tokenizer'
|
||||||
|
|
||||||
export function addGameApis(app, jsonParser) {
|
export function addGameApis(app, jsonParser, memcache) {
|
||||||
app.get('/api/game/:gameId', async (req, res) => {
|
app.get('/api/game/:gameId', async (req, res) => {
|
||||||
try {
|
try {
|
||||||
const game = await Game.findOne({ where: { id: req.params['gameId'] } })
|
const game = await Game.findOne({ where: { id: req.params['gameId'] } })
|
||||||
|
|||||||
27
backend/src/memcache.ts
Normal file
27
backend/src/memcache.ts
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
import { promisify } from 'util'
|
||||||
|
|
||||||
|
var Memcached = require('memcached')
|
||||||
|
|
||||||
|
export class Memcache {
|
||||||
|
readonly memcached
|
||||||
|
|
||||||
|
readonly getCallback
|
||||||
|
readonly setCallback
|
||||||
|
readonly replaceCallback
|
||||||
|
|
||||||
|
constructor(url: string) {
|
||||||
|
this.memcached = new Memcached(url, {})
|
||||||
|
|
||||||
|
this.getCallback = promisify(this.memcached.get).bind(this.memcached)
|
||||||
|
this.setCallback = promisify(this.memcached.set).bind(this.memcached)
|
||||||
|
this.replaceCallback = promisify(this.memcached.replace).bind(this.memcached)
|
||||||
|
}
|
||||||
|
|
||||||
|
async get(key: string) {
|
||||||
|
return this.getCallback(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
async set(key: string, value) {
|
||||||
|
return this.setCallback(key, value, 200)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -43,12 +43,16 @@ function monthIdToEndSeconds(monthId: number): number {
|
|||||||
return Number.MAX_SAFE_INTEGER
|
return Number.MAX_SAFE_INTEGER
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addRushStatsApis(app, jsonParser) {
|
export function addRushStatsApis(app, jsonParser, memcache) {
|
||||||
app.post('/api/serverstats/gamestats', jsonParser, async (req, res) => {
|
app.post('/api/serverstats/gamestats', jsonParser, async (req, res) => {
|
||||||
const monthId = req.body.monthId
|
const monthId = req.body.monthId
|
||||||
let startSeconds = monthIdToStartSeconds(monthId)
|
let startSeconds = monthIdToStartSeconds(monthId)
|
||||||
let endSeconds = monthIdToEndSeconds(monthId)
|
let endSeconds = monthIdToEndSeconds(monthId)
|
||||||
|
|
||||||
|
let cachedResponse = await memcache.get('gamestats' + req.body.monthId)
|
||||||
|
|
||||||
|
if (!cachedResponse) {
|
||||||
|
console.log('cache miss')
|
||||||
const serverGameStats = await database.query(serverGameStatsQuery, {
|
const serverGameStats = await database.query(serverGameStatsQuery, {
|
||||||
type: QueryTypes.SELECT,
|
type: QueryTypes.SELECT,
|
||||||
replacements: {
|
replacements: {
|
||||||
@@ -56,7 +60,13 @@ export function addRushStatsApis(app, jsonParser) {
|
|||||||
endSeconds
|
endSeconds
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await memcache.set('gamestats' + req.body.monthId, serverGameStats[0])
|
||||||
res.send(serverGameStats[0])
|
res.send(serverGameStats[0])
|
||||||
|
} else {
|
||||||
|
console.log('cache hit')
|
||||||
|
res.send(cachedResponse)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
app.post('/api/serverstats/rolestats', jsonParser, async (req, res) => {
|
app.post('/api/serverstats/rolestats', jsonParser, async (req, res) => {
|
||||||
@@ -64,6 +74,9 @@ export function addRushStatsApis(app, jsonParser) {
|
|||||||
let startSeconds = monthIdToStartSeconds(monthId)
|
let startSeconds = monthIdToStartSeconds(monthId)
|
||||||
let endSeconds = monthIdToEndSeconds(monthId)
|
let endSeconds = monthIdToEndSeconds(monthId)
|
||||||
|
|
||||||
|
let cachedResponse = await memcache.get('rolestats' + req.body.monthId)
|
||||||
|
|
||||||
|
if (!cachedResponse) {
|
||||||
const games = await Game.findAll({
|
const games = await Game.findAll({
|
||||||
include: [
|
include: [
|
||||||
{ model: Character, as: 'characterPickedForGame' },
|
{ model: Character, as: 'characterPickedForGame' },
|
||||||
@@ -110,6 +123,11 @@ export function addRushStatsApis(app, jsonParser) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
await memcache.set('rolestats' + req.body.monthId, result)
|
||||||
res.send(result)
|
res.send(result)
|
||||||
|
} else {
|
||||||
|
console.log('cache hit')
|
||||||
|
res.send(cachedResponse)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user