Scrum.ai
Published in

Scrum.ai

Profiling, Refactoring & Design Patterns

Evaluating and enhancing the code

Profiling

node --prof build/server.js
ab -k -c 1000 -n 10000 -T "application/json" -p post.data "http://localhost:3000/slack/events"
node --prof-process isolate-0x102801e00-v8.log  > processed.txt
[Summary]:
ticks total nonlib name
12231 49.0% 50.0% JavaScript
9162 36.7% 37.4% C++
832 3.3% 3.4% GC
497 2.0% Shared libraries
3081 12.3% Unaccounted
[JavaScript]:
ticks total nonlib name
1920 7.7% 7.8% Builtin: StringEqual
941 3.8% 3.8% Builtin: KeyedLoadIC_Megamorphic
860 3.4% 3.5% Builtin: KeyedStoreIC_Megamorphic_Strict
655 2.6% 2.7% LazyCompile: *matchKnownFields _http_incoming.js:150:26
480 1.9% 2.0% LoadIC: A load IC from the snapshot
373 1.5% 1.5% StoreIC: A store IC from the snapshot
362 1.4% 1.5% LazyCompile: *parseBody /Users/rkkautsar/Kuliah/PPL/PPL2018-C1/scrum-bot/node_modules/koa-bodyparser/index.js:89:27
[C++ entry points]:
ticks cpp total name
2242 35.3% 9.0% T v8::internal::Runtime_StringSplit(int, v8::internal::Object**, v8::internal::Isolate*)
1064 16.8% 4.3% T v8::internal::Runtime_GetProperty(int, v8::internal::Object**, v8::internal::Isolate*)
895 14.1% 3.6% T v8::internal::Builtin_HandleApiCall(int, v8::internal::Object**, v8::internal::Isolate*)
748 11.8% 3.0% T v8::internal::Runtime_KeyedGetProperty(int, v8::internal::Object**, v8::internal::Isolate*)
[Summary]:
ticks total nonlib name
117033 45.6% 46.6% JavaScript
97543 38.0% 38.9% C++
10069 3.9% 4.0% GC
5547 2.2% Shared libraries
36407 14.2% Unaccounted
[JavaScript]:
ticks total nonlib name
10274 4.0% 4.1% Builtin: StringEqual
8733 3.4% 3.5% Builtin: KeyedLoadIC_Megamorphic
6871 2.7% 2.7% LoadIC: A load IC from the snapshot
5107 2.0% 2.0% Builtin: KeyedStoreIC_Megamorphic_Strict
4340 1.7% 1.7% LazyCompile: *parseBody /Users/rkkautsar/Kuliah/PPL/PPL2018-C1/scrum-bot/node_modules/koa-bodyparser/index.js:89:27
4039 1.6% 1.6% StoreIC: A store IC from the snapshot {1}
[C++ entry points]:
ticks cpp total name
12083 25.1% 4.7% T v8::internal::Runtime_StringSplit(int, v8::internal::Object**, v8::internal::Isolate*)
8118 16.9% 3.2% T v8::internal::Runtime_KeyedGetProperty(int, v8::internal::Object**, v8::internal::Isolate*)
7039 14.6% 2.7% T v8::internal::Runtime_GetProperty(int, v8::internal::Object**, v8::internal::Isolate*)
5305 11.0% 2.1% T v8::internal::Runtime_SetProperty(int, v8::internal::Object**, v8::internal::Isolate*)

Refactoring

handlers/
NLUHandler extends MessageHandler
SlashCommandHandler extends MessageHandler
slack/handler/
intentHandler(parsedIntent)
{ intent: 'task_add', task_title: 'My Task Title' }

Design Patterns

  1. Chain of responsibility. The handlers I refactored above implements chain of responsibility pattern in the way that it tries every handlers it know until one of it actually handles the message.
  2. Template Method. One of the early feature I’ve coded is the database seeder. It implements template method in the way that it has many seeder that each implements their own seed() function that will be run by the main seeder.
  3. Decorators, Singleton, Builder, and many more. As we use libraries like TypeORM that encourage good patterns, we use their structural and creational patterns to the best that we can.

Appendix

ab -k -c 1000 -n 1000000 -T "application/json" -p post.data "http://localhost:3000/slack/events"
This is ApacheBench, Version 2.3 <$Revision: 1807734 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking localhost (be patient)
Completed 100000 requests
Completed 200000 requests
Completed 300000 requests
Completed 400000 requests
Completed 500000 requests
Completed 600000 requests
Completed 700000 requests
Completed 800000 requests
Completed 900000 requests
Completed 1000000 requests
Finished 1000000 requests
Server Software:
Server Hostname: localhost
Server Port: 3000
Document Path: /slack/events
Document Length: 2 bytes
Concurrency Level: 1000
Time taken for tests: 304.648 seconds
Complete requests: 1000000
Failed requests: 0
Keep-Alive requests: 1000000
Total transferred: 142000000 bytes
Total body sent: 275000000
HTML transferred: 2000000 bytes
Requests per second: 3282.47 [#/sec] (mean)
Time per request: 304.648 [ms] (mean)
Time per request: 0.305 [ms] (mean, across all concurrent requests)
Transfer rate: 455.19 [Kbytes/sec] received
881.52 kb/s sent
1336.71 kb/s total
Connection Times (ms)
min mean[+/-sd] median max
Connect: 0 0 1.9 0 93
Processing: 17 304 126.6 261 1741
Waiting: 17 304 126.6 261 1741
Total: 22 305 126.6 261 1741
Percentage of the requests served within a certain time (ms)
50% 261
66% 276
75% 293
80% 322
90% 431
95% 547
98% 738
99% 855
100% 1741 (longest request)

--

--

A Scrum Bot project on top of Kata.ai

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store