Skip to content

Commit

Permalink
create interface for storage and wrap in-memory implementation in it
Browse files Browse the repository at this point in the history
  • Loading branch information
darthfiddler authored and nicolodavis committed Dec 19, 2017
1 parent e905983 commit 6272a5d
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 7 deletions.
43 changes: 43 additions & 0 deletions src/server/db.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

/**
* InMemory data storage.
*/
export class InMemory {

This comment has been minimized.

Copy link
@saeidalidadi

saeidalidadi Dec 19, 2017

Contributor

Using Map class would be another option

This comment has been minimized.

Copy link
@nicolodavis

nicolodavis Dec 20, 2017

Member

Fixed in b66e0a9

/**
* Creates a new InMemory storage.
* @param {function} reducer - The game reducer.
*/
constructor(reducer) {
this.reducer = reducer;

This comment has been minimized.

Copy link
@ciocan

ciocan Dec 19, 2017

when is this used?

This comment has been minimized.

Copy link
@nicolodavis

nicolodavis Dec 20, 2017

Member

Fixed in b66e0a9

this.obj = {};
}

/**
* Write the game state to the in-memory object.
* @param {string} id - The game id.
* @param {object} store - A Redux store to persist.
*/
set(id, store) {
this.obj[id] = store;
}

/**
* Read the game state from the in-memory object.
* @param {string} id - The game id.
* @returns {object} - A Redux store with the game state, or null
* if no game is found with this id.
*/
get(id) {
if (id in this.obj) {
return this.obj[id];
}
return null;
}
}
23 changes: 23 additions & 0 deletions src/server/db.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright 2017 Google Inc.
*
* Use of this source code is governed by a MIT-style
* license that can be found in the LICENSE file or at
* https://opensource.org/licenses/MIT.
*/

import { InMemory } from './db';
import * as Redux from 'redux';

test('basic', () => {
const db = new InMemory();
const reducer = () => {};
const store = Redux.createStore(reducer);

// Must return null when no game exists.
expect(db.get('gameid')).toEqual(null);
// Create game.
db.set('gameid', store);
// Must return created game.
expect(db.get('gameid')).toEqual(store);
});
18 changes: 11 additions & 7 deletions src/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,9 @@
const Koa = require('koa');
const IO = require('koa-socket');
const Redux = require('redux');
import { InMemory } from './db';
import { createGameReducer } from '../both/reducer';

const games = {};

function Server({game, numPlayers}) {
const app = new Koa();
const io = new IO();
Expand All @@ -21,32 +20,37 @@ function Server({game, numPlayers}) {
io.attach(app);

const reducer = createGameReducer({game, numPlayers});
const db = new InMemory(reducer);

io.on('connection', (ctx) => {
const socket = ctx.socket;

socket.on('action', action => {
const gameid = action._gameid;
const store = db.get(gameid);

if (!(gameid in games)) {
if (store == null) {
return { error: 'game not found' };
}

const store = games[gameid];
const state = store.getState();

if (state._id == action._id) {
store.dispatch(action);
socket.broadcast.emit('action', action);
db.set(gameid, store);
}
});

socket.on('sync', gameid => {
if (!(gameid in games)) {
games[gameid] = Redux.createStore(reducer);
let store = null;
if (db.get(gameid) == null) {
store = Redux.createStore(reducer);
db.set(gameid, store);

This comment has been minimized.

Copy link
@saeidalidadi

saeidalidadi Dec 20, 2017

Contributor

Do you have any idea to persist this store state on mongodb

This comment has been minimized.

Copy link
@saeidalidadi

saeidalidadi Dec 20, 2017

Contributor

We could add async state reducers. here

} else {
store = db.get(gameid);
}

const store = games[gameid];
const state = store.getState();
socket.emit('sync', state);
});
Expand Down
2 changes: 2 additions & 0 deletions src/server/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,8 @@ test('action', () => {
io.socket.receive('action', action);
expect(io.socket.broadcast.emit.mock.calls.length).toBe(0);

io.socket.receive('sync', 'gameid');

// Actions are broadcasted.
action._gameid = 'gameid';
action._id = 0;
Expand Down

1 comment on commit 6272a5d

@nicolodavis
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#6

Please sign in to comment.