Skip to content

Instantly share code, notes, and snippets.

@aoberoi
Last active November 12, 2016 00:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aoberoi/6e8a8a9902d3dfd4cd112088e5a54815 to your computer and use it in GitHub Desktop.
Save aoberoi/6e8a8a9902d3dfd4cd112088e5a54815 to your computer and use it in GitHub Desktop.
Node Slack SDK Issue 252 Experiment
node_modules
.git
memstats
node_modules
teams.csv
*.log

Node Slack SDK Issue 252 Experiment

Setup

  1. Create a teams.csv file with the teams you will connect to. The goal is to have 1000 connections, so I used 100 teams and an xoxp token for each team. Then in the code there is a for loop that makes 10 connections per team. You can adjust that factor according to your goals. Use teams.csv.sample as a template.

  2. npm install

Running the test

node index.js.

You will start to see log statements about connections being connected and disconnected. Once the connections seem stable (no more log statements for ~10 seconds) make sure at least one GC occurs (a log statement that says stats received), and then toggle your connection state. That means if you started the test with your network connection on, turn it off, and vice versa.

Results

The results will be written to a timestamped csv file beginning with memstats-. The most interesting column in this file will be estimated_base. You can visualize the results in a spreadsheet.

Note that each of the stats received log statements correspond to one row in the results file. In order to interpret when certain network connection changes occurred, you can count the number of those messages before each toggle and then find them in the results. The last two columns, clients_connected and clients_reconnecting, tell you how many of the connections were either connected or disconnected, respectively.

Docker Stuff

I did at some point run this in a container but then I realized I didn't need to, so I stopped looking at it. It may or may not work, so don't trust it.

FROM node:boron
MAINTAINER Ankur Oberoi <aoberoi@gmail.com>
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY package.json /usr/src/app/
RUN npm install
COPY . /usr/src/app
RUN groupadd -r app && useradd -r -g app app
USER app
CMD ["node", "index.js"]
const RtmClient = require('@slack/client').RtmClient;
const CLIENT_EVENTS = require('@slack/client').CLIENT_EVENTS;
const fs = require('fs');
const parse = require('csv-parse/lib/sync');
const memwatch = require('memwatch-next');
const resultsFilename = `./memstats-${Date.now()}.csv`;
const teamsFileContents = fs.readFileSync('./teams.csv', 'utf8');
const teams = parse(teamsFileContents, { columns: true });
const clients = [];
let nextClientNum = 0;
function createClient(team) {
const rtm = new RtmClient(team.member_xoxp_token, {
slackAPIUrl: 'https://qa.slack.com/api/',
// Uncomment to run test with no MemoryDataStore
// dataStore: null,
});
const clientInfo = {
clientNum: nextClientNum,
rtm,
connected: false,
};
nextClientNum += 1;
rtm.on(CLIENT_EVENTS.RTM.RTM_CONNECTION_OPENED, () => {
console.log(`client ${clientInfo.clientNum} connected`);
clientInfo.connected = true;
});
rtm.on(CLIENT_EVENTS.RTM.ATTEMPTING_RECONNECT, () => {
console.log(`client ${clientInfo.clientNum} reconnecting`);
clientInfo.connected = false;
});
rtm.start();
clients.push(clientInfo);
}
for (let i = 0; i < teams.length; i++) {
for (let j = 0; j < 10; j++) {
createClient(teams[i]);
}
}
memwatch.on('leak', (info) => {
console.warn('leak detected');
console.dir(info);
// Uncomment to insert leak info into results file
// fs.appendFile(resultsFilename, JSON.stringify(info) + '\n');
});
let firstLine = true;
memwatch.on('stats', (stats) => {
console.log('stats received');
let info = [];
if (firstLine) {
info.push('num_full_gc');
info.push('num_inc_gc');
info.push('heap_compactions');
info.push('usage_trend');
info.push('estimated_base');
info.push('current_base');
info.push('min');
info.push('max');
info.push('clients_connected');
info.push('clients_reconnecting');
fs.appendFileSync(resultsFilename, info.join(',') + '\n');
info = [];
firstLine = false;
}
info.push(stats['num_full_gc']);
info.push(stats['num_inc_gc']);
info.push(stats['heap_compactions']);
info.push(stats['usage_trend']);
info.push(stats['estimated_base']);
info.push(stats['current_base']);
info.push(stats['min']);
info.push(stats['max']);
info.push(clients.filter(c => c.connected).length);
info.push(clients.filter(c => !c.connected).length);
fs.appendFile(resultsFilename, info.join(',') + '\n');
});
{
"name": "node-slack-sdk-252",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "node index.js"
},
"author": "",
"license": "ISC",
"dependencies": {
"@slack/client": "^3.6.0",
"csv-parse": "^1.1.7",
"memwatch-next": "^0.3.0"
}
}
team_id,member_xoxp_token
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment