Skip to content

Commit

Permalink
#7 Feat: implement in-memory stroage as a service
Browse files Browse the repository at this point in the history
  • Loading branch information
IvanBlacky committed Feb 4, 2019
1 parent 9cef7ea commit 09eb4ad
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 45 deletions.
52 changes: 8 additions & 44 deletions src/controllers/Whitelist.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,59 +3,23 @@ const BasicController = core.controllers.Basic;
const Whitelist = require('../model/Whitelist');

class WhitelistController extends BasicController {
constructor({ connector }) {
constructor({ connector, storage }) {
super({ connector });

this._whitelistMap = new Map(); // user -> set of cids
this._cidSet = new Set(); // set of cids
this._storage = storage;
}

async _askRegService({ user }) {
// TODO: implement call to service
return true;
return this.callService('registration', 'registration.isRegistered', { user });
}

async handleOffline({ user, channelId }) {
this._cidSet.delete(channelId);

if (this._whitelistMap.has(user)) {
const mappedSet = this._whitelistMap.get(user);

mappedSet.delete(channelId);

if (mappedSet.size === 0) this._whitelistMap.delete(user);
}
}

_addInMemoryDb({ user, channelId }) {
this._cidSet.add(channelId);

let userCids = this._whitelistMap.get(user);

if (userCids) {
userCids.add(channelId);
} else {
userCids = new Set([channelId]);
}

this._whitelistMap.set(user, userCids);
}

_removeFromMemoryDb(user) {
const cids = this._whitelistMap.get(user);

if (cids) {
cids.forEach(cid => {
this._cidSet.delete(cid);
});
}

this._whitelistMap.delete(user);
this._storage.handleOffline({ user, channelId });
}

async isAllowed({ channelId, user }) {
// in memory -> allowed
if (this._cidSet.has(channelId)) return true;
if (this._storage.isStored({ channelId, user })) return true;

const dbUser = await Whitelist.findOne({ user });

Expand All @@ -66,7 +30,7 @@ class WhitelistController extends BasicController {

// in db -> allowed and should be stored in memory
if (dbUser && !dbUser.banned) {
this._addInMemoryDb({ user: dbUser.user, channelId });
this._storage.addInMemoryDb({ user: dbUser.user, channelId });

return true;
}
Expand All @@ -79,15 +43,15 @@ class WhitelistController extends BasicController {

// in reg service -> add to mongo and to in-mem
await Whitelist.create({ user, banned: false });
this._addInMemoryDb({ user, channelId });
this._storage.addInMemoryDb({ user, channelId });

return true;
}

async banUser(user) {
await Whitelist.findOneAndUpdate({ user }, { banned: true });

this._removeFromMemoryDb(user);
this._storage.removeFromMemoryDb(user);
}
}

Expand Down
1 change: 1 addition & 0 deletions src/data/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ module.exports = {
GLS_CONNECTOR_PORT: env.GLS_CONNECTOR_PORT || 3000,
GLS_PROVIDER_WIF: env.GLS_PROVIDER_WIF,
GLS_PROVIDER_USERNAME: env.GLS_PROVIDER_USERNAME,
GLS_CHANNEL_TTL: env.GLS_CHANNEL_TTL || 1000,
};
9 changes: 8 additions & 1 deletion src/services/Connector.js
Original file line number Diff line number Diff line change
@@ -1,22 +1,29 @@
const core = require('gls-core-service');
const BasicConnector = core.services.Connector;
const BandwidthProvider = require('./BandwidthProvider');
const StorageService = require('./StorageService');
const Whitelist = require('../controllers/Whitelist');

class Connector extends BasicConnector {
constructor() {
super();
this._whitelistController = new Whitelist({ connector: this });
this._storageService = new StorageService();
this._whitelistController = new Whitelist({
connector: this,
storage: this._storageService,
});
this._bandwidthProvider = new BandwidthProvider({
whitelist: this._whitelistController,
});
}

async start() {
const storage = this._storageService;
const provider = this._bandwidthProvider;
const whitelist = this._whitelistController;

await provider.start();
await storage.start();

this.on('open', data => {
console.log(data);
Expand Down
95 changes: 95 additions & 0 deletions src/services/StorageService.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
const core = require('gls-core-service');
const BasicService = core.services.Basic;
const env = require('../data/env');
const { GLS_CHANNEL_TTL } = env;

class Storage extends BasicService {
constructor() {
super();

this._whitelistMap = new Map(); // user -> set of cids
this._cidSet = new Set(); // set of cids
this._timeoutMap = new Map(); // channelId -> last request
}

async start() {
const interval = 1000 * 60; // one hour
// const interval = 1000 * 60 * 60; // one hour
setInterval(this._cleanup.bind(this), interval);
}

_cleanup() {
const now = Date.now();
this._timeoutMap.forEach((lastRequestDate, channelId) => {
const shouldBeDeleted = now - lastRequestDate >= GLS_CHANNEL_TTL;

if (shouldBeDeleted) {
this._timeoutMap.delete(channelId);
this._cidSet.delete(channelId);

this._whitelistMap.forEach((cidSet, username) => {
if (cidSet.has(channelId)) {
cidSet.delete(channelId);
if (cidSet.size === 0) {
this._whitelistMap.delete(username);
}
}
});
}
});
}

isStored({ user, channelId }) {
const now = new Date();
const stored = this._whitelistMap.has(user) || this._cidSet.has(channelId);

if (channelId) this._timeoutMap.set(channelId, now);

return stored;
}

addInMemoryDb({ user, channelId }) {
const now = new Date();

this._cidSet.add(channelId);

let userCids = this._whitelistMap.get(user);

if (userCids) {
userCids.add(channelId);
} else {
userCids = new Set([channelId]);
}

this._whitelistMap.set(user, userCids);

this._timeoutMap.set(channelId, now);
}

removeFromMemoryDb(user) {
const cids = this._whitelistMap.get(user);

if (cids) {
cids.forEach(cid => {
this._cidSet.delete(cid);
this._timeoutMap.delete(cid);
});
}

this._whitelistMap.delete(user);
}

handleOffline({ user, channelId }) {
this._cidSet.delete(channelId);

if (this._whitelistMap.has(user)) {
const mappedSet = this._whitelistMap.get(user);

mappedSet.delete(channelId);

if (mappedSet.size === 0) this._whitelistMap.delete(user);
}
}
}

module.exports = Storage;

0 comments on commit 09eb4ad

Please sign in to comment.