<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Frank@theOpenSourceU.org</title>
    <description>The latest articles on DEV Community by Frank@theOpenSourceU.org (@theopensourceu).</description>
    <link>https://dev.to/theopensourceu</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F58629%2F10743851-bf02-4c04-b52e-b47d1e5e89df.jpg</url>
      <title>DEV Community: Frank@theOpenSourceU.org</title>
      <link>https://dev.to/theopensourceu</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/theopensourceu"/>
    <language>en</language>
    <item>
      <title>Revisited Concept: High Performance web server w/ Promises</title>
      <dc:creator>Frank@theOpenSourceU.org</dc:creator>
      <pubDate>Wed, 14 Mar 2018 13:53:00 +0000</pubDate>
      <link>https://dev.to/theopensourceu/revisited-concept-high-performance-web-server-w-promises--1f70</link>
      <guid>https://dev.to/theopensourceu/revisited-concept-high-performance-web-server-w-promises--1f70</guid>
      <description>

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--T1RvBYgm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1520764816423-52375cbff016%3Fixlib%3Drb-0.3.5%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D1080%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ%26s%3De533e5b4614cdb82fe0651d8ae79a0b0" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--T1RvBYgm--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://images.unsplash.com/photo-1520764816423-52375cbff016%3Fixlib%3Drb-0.3.5%26q%3D80%26fm%3Djpg%26crop%3Dentropy%26cs%3Dtinysrgb%26w%3D1080%26fit%3Dmax%26ixid%3DeyJhcHBfaWQiOjExNzczfQ%26s%3De533e5b4614cdb82fe0651d8ae79a0b0" alt="Revisited Concept: High Performance web server w/ Promises"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://theopensourceu.org/revisited-concept-high-performance-web-server-promises/"&gt;This is a follow up&lt;/a&gt; to my earlier article: &lt;a href="https://theopensourceu.org/concept-high-performance-web-server-w-promises/"&gt;Concept: High Performance web server w/ Promises&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I decided to follow this up for two main reasons. First and foremost, there was an error in the original code I posted and I couldn't remember if that error existed in the code I actually tested with or if it was introduced during my writing of the article. Second, I didn't have any of my detailed data to share and I feel that is relevant to this type of article.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Concept
&lt;/h2&gt;

&lt;p&gt;The &lt;em&gt;TL;DR&lt;/em&gt; of the concept is: Can we get higher HTTP server throughput (higher RPS) by using a promise even when not needed. That is, no async operation exists.&lt;/p&gt;

&lt;p&gt;Please see the &lt;a href="https://theopensourceu.org/concept-high-performance-web-server-w-promises/"&gt;first article for more details&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Methodology
&lt;/h2&gt;

&lt;p&gt;I recreated my project but this time I saved it as &lt;a href="https://github.com/TheOpenSourceU/tOSU-PromiseWebServer-Experiment"&gt;open source&lt;/a&gt;. It's a basic &lt;a href="https://www.jetbrains.com/webstorm/"&gt;WebStorm&lt;/a&gt; express template with &lt;a href="https://handlebarsjs.com/"&gt;handlebars&lt;/a&gt; as the view manager. I've modified it to introduce my concept and that looks like:&lt;/p&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const myData = { title: 'Promise Express' };

/* GET /promise/ */
router.get('/', function(req, res) {
    new Promise(function(resolve, reject) {
        resolve(myData); //setup data
    }).then(function(d) {
        res.render('index', d); //render the view in the 'then'
    });
});
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;I used &lt;a href="https://artillery.io/docs/getting-started/"&gt;Artillery&lt;/a&gt; for the load testing aspect. Artillery was run from my desktop computer (not on the server running the express project). Using &lt;a href="https://artillery.io/docs/getting-started/"&gt;Artillery&lt;/a&gt;, we create the following scenarios:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10 users each making 20 GET requests&lt;/li&gt;
&lt;li&gt;50 users each making 30 GET requests&lt;/li&gt;
&lt;li&gt;100 users each making 30 GET requests&lt;/li&gt;
&lt;li&gt;500 users each making 100 GET requests&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exact server details are: &lt;a href="https://theopensourceu.org/tag/linux/"&gt;Ubuntu 16.04 LTS&lt;/a&gt; &lt;a href="https://m.do.co/c/0595daf97871"&gt;DigitalOcean Droplets&lt;/a&gt;, Flexible Droplets - 2 GB 2x vCPUs ($15 a month).&lt;/p&gt;

&lt;p&gt;Note: I also did one run on a 1 GB 1x vCPU droplet as well which is documented at the very bottom.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary of Differences
&lt;/h2&gt;

&lt;p&gt;There are a few technical differences from my initial article and this version aside from the depth of content. ( &lt;strong&gt;Format&lt;/strong&gt; : &lt;em&gt;first article&lt;/em&gt; vs &lt;em&gt;this article&lt;/em&gt;)&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Promise library: &lt;a href="https://github.com/floatdrop/pinkie-promise"&gt;Pinkie&lt;/a&gt; vs &lt;a href="http://bluebirdjs.com/docs/getting-started.html"&gt;Bluebird&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;The server: 1x CPU, 1 GB VPS vs 2x CPU, 2 GiB VPS

&lt;ul&gt;
&lt;li&gt;I did check the prev. config though without getting errors.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Handlebars: No view template engine vs Handlebars&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;The results are different than my first article. Basically, it doesn't help but it doesn't hurt...&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--K0RwbY5k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://theopensourceu.org/content/images/2018/03/chart.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--K0RwbY5k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://theopensourceu.org/content/images/2018/03/chart.PNG" alt="Revisited Concept: High Performance web server w/ Promises"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No scenario threw any errors (which was different from my first run as I recall.) &lt;em&gt;I've made the assumption that this has to do with my promise library of choice; &lt;a href="http://bluebirdjs.com/docs/benchmarks.html"&gt;bluebird is known and written to be very fast&lt;/a&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Raw Results
&lt;/h1&gt;

&lt;p&gt;Following are the "&lt;em&gt;cut and paste&lt;/em&gt;" raw results from Artillery for detailed reference and review. Also, in case I mistyped something into a chart or table.&lt;/p&gt;

&lt;h1&gt;
  
  
  2x vCPU, 2 GiB RAM
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Basic - 10 "Virtual Users", 20 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 10 -n 20 http://159.65.99.177:3000/basic
Started phase 0, duration: 1s @ 15:00:41(-0600) 2018-03-06
Report @ 15:00:44(-0600) 2018-03-06
  Scenarios launched: 10
  Scenarios completed: 10
  Requests completed: 200
  RPS sent: 68.49
  Request latency:
    min: 64.3
    max: 139.3
    median: 71.8
    p95: 119.8
    p99: 137.9
  Codes:
    200: 200

All virtual users finished
Summary report @ 15:00:44(-0600) 2018-03-06
  Scenarios launched: 10
  Scenarios completed: 10
  Requests completed: 200
  RPS sent: 68.03
  Request latency:
    min: 64.3
    max: 139.3
    median: 71.8
    p95: 119.8
    p99: 137.9
  Scenario counts:
    0: 10 (100%)
  Codes:
    200: 200
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Promise - 10 "Virtual Users", 20 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 10 -n 20 http://159.65.99.177:3000/promise
Started phase 0, duration: 1s @ 15:01:44(-0600) 2018-03-06
Report @ 15:01:47(-0600) 2018-03-06
  Scenarios launched: 10
  Scenarios completed: 10
  Requests completed: 200
  RPS sent: 82.64
  Request latency:
    min: 62.3
    max: 144.8
    median: 71.1
    p95: 116.5
    p99: 140.7
  Codes:
    200: 200

All virtual users finished
Summary report @ 15:01:47(-0600) 2018-03-06
  Scenarios launched: 10
  Scenarios completed: 10
  Requests completed: 200
  RPS sent: 82.3
  Request latency:
    min: 62.3
    max: 144.8
    median: 71.1
    p95: 116.5
    p99: 140.7
  Scenario counts:
    0: 10 (100%)
  Codes:
    200: 200
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic - 50 "Virtual Users", 30 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 50 -n 30 http://159.65.99.177:3000/basic
Started phase 0, duration: 1s @ 15:06:18(-0600) 2018-03-06
Report @ 15:06:22(-0600) 2018-03-06
  Scenarios launched: 50
  Scenarios completed: 50
  Requests completed: 1500
  RPS sent: 373.13
  Request latency:
    min: 63
    max: 376.4
    median: 84.5
    p95: 130.4
    p99: 149.2
  Codes:
    200: 1500

All virtual users finished
Summary report @ 15:06:22(-0600) 2018-03-06
  Scenarios launched: 50
  Scenarios completed: 50
  Requests completed: 1500
  RPS sent: 372.21
  Request latency:
    min: 63
    max: 376.4
    median: 84.5
    p95: 130.4
    p99: 149.2
  Scenario counts:
    0: 50 (100%)
  Codes:
    200: 1500
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Promise - 50 "Virtual Users", 30 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 50 -n 30 http://159.65.99.177:3000/promise
Started phase 0, duration: 1s @ 15:06:57(-0600) 2018-03-06
Report @ 15:07:01(-0600) 2018-03-06
  Scenarios launched: 50
  Scenarios completed: 50
  Requests completed: 1500
  RPS sent: 374.06
  Request latency:
    min: 63.2
    max: 360.3
    median: 82.6
    p95: 132.8
    p99: 166
  Codes:
    200: 1500

All virtual users finished
Summary report @ 15:07:01(-0600) 2018-03-06
  Scenarios launched: 50
  Scenarios completed: 50
  Requests completed: 1500
  RPS sent: 372.21
  Request latency:
    min: 63.2
    max: 360.3
    median: 82.6
    p95: 132.8
    p99: 166
  Scenario counts:
    0: 50 (100%)
  Codes:
    200: 1500
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic - 100 "Virtual Users", 30 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 100 -n 30 http://159.65.99.177:3000/basic
Started phase 0, duration: 2s @ 15:11:15(-0600) 2018-03-06
Report @ 15:11:21(-0600) 2018-03-06
  Scenarios launched: 100
  Scenarios completed: 100
  Requests completed: 3000
  RPS sent: 543.48
  Request latency:
    min: 62.3
    max: 220.3
    median: 114
    p95: 155.4
    p99: 174.5
  Codes:
    200: 3000

All virtual users finished
Summary report @ 15:11:21(-0600) 2018-03-06
  Scenarios launched: 100
  Scenarios completed: 100
  Requests completed: 3000
  RPS sent: 541.52
  Request latency:
    min: 62.3
    max: 220.3
    median: 114
    p95: 155.4
    p99: 174.5
  Scenario counts:
    0: 100 (100%)
  Codes:
    200: 3000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Promise - 100 "Virtual Users", 30 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 100 -n 30 http://159.65.99.177:3000/promise
Started phase 0, duration: 2s @ 15:12:23(-0600) 2018-03-06
Report @ 15:12:28(-0600) 2018-03-06
  Scenarios launched: 100
  Scenarios completed: 100
  Requests completed: 3000
  RPS sent: 542.5
  Request latency:
    min: 63.6
    max: 240.4
    median: 117.1
    p95: 196.8
    p99: 209.9
  Codes:
    200: 3000

All virtual users finished
Summary report @ 15:12:28(-0600) 2018-03-06
  Scenarios launched: 100
  Scenarios completed: 100
  Requests completed: 3000
  RPS sent: 540.54
  Request latency:
    min: 63.6
    max: 240.4
    median: 117.1
    p95: 196.8
    p99: 209.9
  Scenario counts:
    0: 100 (100%)
  Codes:
    200: 3000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic - 200 "Virtual Users", 50 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 200 -n 50 http://159.65.99.177:3000/basic
Started phase 0, duration: 4s @ 15:21:01(-0600) 2018-03-06
Report @ 15:21:11(-0600) 2018-03-06
  Scenarios launched: 200
  Scenarios completed: 0
  Requests completed: 5737
  RPS sent: 592.91
  Request latency:
    min: 62.1
    max: 528.2
    median: 272
    p95: 403.4
    p99: 431.9
  Codes:
    200: 5737

Report @ 15:21:17(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 200
  Requests completed: 4263
  RPS sent: 735.08
  Request latency:
    min: 66.1
    max: 552.1
    median: 214.4
    p95: 272.9
    p99: 289.2
  Codes:
    200: 4263

All virtual users finished
Summary report @ 15:21:17(-0600) 2018-03-06
  Scenarios launched: 200
  Scenarios completed: 200
  Requests completed: 10000
  RPS sent: 641.03
  Request latency:
    min: 62.1
    max: 552.1
    median: 245.8
    p95: 382.5
    p99: 424.9
  Scenario counts:
    0: 200 (100%)
  Codes:
    200: 10000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Promise - 200 "Virtual Users", 50 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 200 -n 50 http://159.65.99.177:3000/promise
Started phase 0, duration: 4s @ 15:22:10(-0600) 2018-03-06
Report @ 15:22:20(-0600) 2018-03-06
  Scenarios launched: 200
  Scenarios completed: 0
  Requests completed: 5664
  RPS sent: 585.81
  Request latency:
    min: 65.7
    max: 468.6
    median: 290.4
    p95: 384.7
    p99: 414.3
  Codes:
    200: 5664

Report @ 15:22:27(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 200
  Requests completed: 4336
  RPS sent: 589.17
  Request latency:
    min: 62.7
    max: 433.5
    median: 249.1
    p95: 375.4
    p99: 408.7
  Codes:
    200: 4336

All virtual users finished
Summary report @ 15:22:27(-0600) 2018-03-06
  Scenarios launched: 200
  Scenarios completed: 200
  Requests completed: 10000
  RPS sent: 585.14
  Request latency:
    min: 62.7
    max: 468.6
    median: 270.6
    p95: 381.6
    p99: 410
  Scenario counts:
    0: 200 (100%)
  Codes:
    200: 10000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Basic - 500 "Virtual Users", 100 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 500 -n 100 http://159.65.99.177:3000/basic
Started phase 0, duration: 10s @ 15:27:51(-0600) 2018-03-06
Report @ 15:28:01(-0600) 2018-03-06
  Scenarios launched: 499
  Scenarios completed: 0
  Requests completed: 2969
  RPS sent: 347.05
  Request latency:
    min: 68.3
    max: 1459.7
    median: 657.3
    p95: 1170.9
    p99: 1273.4
  Codes:
    200: 2969

Report @ 15:28:11(-0600) 2018-03-06
  Scenarios launched: 1
  Scenarios completed: 0
  Requests completed: 3221
  RPS sent: 322.3
  Request latency:
    min: 1228.9
    max: 2406.5
    median: 1474.4
    p95: 2157.3
    p99: 2234.8
  Codes:
    200: 3221

Report @ 15:28:21(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3465
  RPS sent: 347.19
  Request latency:
    min: 1170.7
    max: 1972.4
    median: 1472.9
    p95: 1591.9
    p99: 1623.6
  Codes:
    200: 3465

Report @ 15:28:31(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 2944
  RPS sent: 295.29
  Request latency:
    min: 1336.3
    max: 2194.1
    median: 1659.1
    p95: 1851.4
    p99: 1917.3
  Codes:
    200: 2944

Report @ 15:28:41(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 2695
  RPS sent: 269.5
  Request latency:
    min: 1511
    max: 2925.6
    median: 1708.7
    p95: 2599.9
    p99: 2763
  Codes:
    200: 2695

Report @ 15:28:51(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3173
  RPS sent: 317.3
  Request latency:
    min: 1215.4
    max: 2177.5
    median: 1605.9
    p95: 1855.3
    p99: 1914.4
  Codes:
    200: 3173

Report @ 15:29:01(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3103
  RPS sent: 311.55
  Request latency:
    min: 1365.4
    max: 2064.8
    median: 1575.2
    p95: 1790.9
    p99: 1839.5
  Codes:
    200: 3103

Report @ 15:29:11(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3926
  RPS sent: 392.21
  Request latency:
    min: 1007.3
    max: 1879
    median: 1298.1
    p95: 1652.6
    p99: 1695.8
  Codes:
    200: 3926

Report @ 15:29:21(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3500
  RPS sent: 351.05
  Request latency:
    min: 1035.3
    max: 2560.6
    median: 1223.3
    p95: 2261.8
    p99: 2317.5
  Codes:
    200: 3500

Report @ 15:29:31(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3762
  RPS sent: 375.82
  Request latency:
    min: 892
    max: 2616
    median: 1372.8
    p95: 1992.1
    p99: 2263.5
  Codes:
    200: 3762

Report @ 15:29:41(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 4787
  RPS sent: 478.22
  Request latency:
    min: 872.3
    max: 1304.4
    median: 1029.1
    p95: 1211.3
    p99: 1256.7
  Codes:
    200: 4787

Report @ 15:29:51(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 2
  Requests completed: 4288
  RPS sent: 429.89
  Request latency:
    min: 955.4
    max: 1546.2
    median: 1154.3
    p95: 1316
    p99: 1342.4
  Codes:
    200: 4288

Report @ 15:30:01(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 43
  Requests completed: 3345
  RPS sent: 330.86
  Request latency:
    min: 1169.9
    max: 2025.5
    median: 1439.5
    p95: 1695.3
    p99: 1735.2
  Codes:
    200: 3345

Report @ 15:30:11(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 128
  Requests completed: 3091
  RPS sent: 297.19
  Request latency:
    min: 1062.3
    max: 2158.7
    median: 1313.9
    p95: 1688.9
    p99: 1725.6
  Codes:
    200: 3091

Report @ 15:30:17(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 327
  Requests completed: 1731
  RPS sent: 256.67
  Request latency:
    min: 67.3
    max: 1544.1
    median: 812.7
    p95: 1134.7
    p99: 1194.8
  Codes:
    200: 1731

All virtual users finished
Summary report @ 15:30:17(-0600) 2018-03-06
  Scenarios launched: 500
  Scenarios completed: 500
  Requests completed: 50000
  RPS sent: 342.4
  Request latency:
    min: 67.3
    max: 2925.6
    median: 1343.2
    p95: 1868.3
    p99: 2289
  Scenario counts:
    0: 500 (100%)
  Codes:
    200: 50000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Promise - 500 "Virtual Users", 100 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 500 -n 100 http://159.65.99.177:3000/promise
Started phase 0, duration: 10s @ 15:23:49(-0600) 2018-03-06
Report @ 15:23:59(-0600) 2018-03-06
  Scenarios launched: 499
  Scenarios completed: 0
  Requests completed: 2840
  RPS sent: 334.13
  Request latency:
    min: 73.3
    max: 1409
    median: 838
    p95: 1189.6
    p99: 1291.6
  Codes:
    200: 2840

Report @ 15:24:09(-0600) 2018-03-06
  Scenarios launched: 1
  Scenarios completed: 0
  Requests completed: 3281
  RPS sent: 328.3
  Request latency:
    min: 1109.5
    max: 2140.4
    median: 1508.1
    p95: 1780.6
    p99: 1811.6
  Codes:
    200: 3281

Report @ 15:24:19(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3164
  RPS sent: 316.4
  Request latency:
    min: 1341.6
    max: 2064.7
    median: 1568.2
    p95: 1747.3
    p99: 1788.5
  Codes:
    200: 3164

Report @ 15:24:29(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3389
  RPS sent: 338.9
  Request latency:
    min: 1130.1
    max: 2303.4
    median: 1441.1
    p95: 1931.9
    p99: 2009.6
  Codes:
    200: 3389

Report @ 15:24:39(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3653
  RPS sent: 365.3
  Request latency:
    min: 1129.9
    max: 1912.8
    median: 1344
    p95: 1672
    p99: 1750.4
  Codes:
    200: 3653

Report @ 15:24:49(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3239
  RPS sent: 323.8
  Request latency:
    min: 1177.4
    max: 2181.4
    median: 1541.4
    p95: 1996.8
    p99: 2080.1
  Codes:
    200: 3239

Report @ 15:24:59(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3167
  RPS sent: 316.7
  Request latency:
    min: 1211.1
    max: 2267.6
    median: 1557
    p95: 1819.5
    p99: 1874.5
  Codes:
    200: 3167

Report @ 15:25:09(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3285
  RPS sent: 328.6
  Request latency:
    min: 1291.1
    max: 2083.3
    median: 1534.9
    p95: 1748.2
    p99: 1818.5
  Codes:
    200: 3285

Report @ 15:25:20(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3217
  RPS sent: 322.02
  Request latency:
    min: 1195
    max: 2412.1
    median: 1554.5
    p95: 1967.8
    p99: 2017.9
  Codes:
    200: 3217

Report @ 15:25:30(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3744
  RPS sent: 375.53
  Request latency:
    min: 1024.8
    max: 1831.5
    median: 1325
    p95: 1604.3
    p99: 1667.5
  Codes:
    200: 3744

Report @ 15:25:40(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3376
  RPS sent: 337.6
  Request latency:
    min: 1266.4
    max: 1897.7
    median: 1509.7
    p95: 1641.8
    p99: 1688.3
  Codes:
    200: 3376

Report @ 15:25:50(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 3311
  RPS sent: 331.1
  Request latency:
    min: 1124.3
    max: 2060.3
    median: 1534.3
    p95: 1781.6
    p99: 1822.9
  Codes:
    200: 3311

Report @ 15:26:00(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 10
  Requests completed: 3122
  RPS sent: 312.45
  Request latency:
    min: 1254.5
    max: 2007.5
    median: 1627.3
    p95: 1750.8
    p99: 1789.1
  Codes:
    200: 3122

Report @ 15:26:10(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 50
  Requests completed: 3369
  RPS sent: 332.23
  Request latency:
    min: 1104.9
    max: 1970.4
    median: 1416.5
    p95: 1659.1
    p99: 1730.9
  Codes:
    200: 3369

Report @ 15:26:20(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 209
  Requests completed: 3203
  RPS sent: 299.4
  Request latency:
    min: 827.1
    max: 1679.7
    median: 1181.5
    p95: 1464.4
    p99: 1502.7
  Codes:
    200: 3203

Report @ 15:26:22(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 231
  Requests completed: 640
  RPS sent: 162.95
  Request latency:
    min: 118.2
    max: 944.7
    median: 790.7
    p95: 894
    p99: 928.5
  Codes:
    200: 640

All virtual users finished
Summary report @ 15:26:22(-0600) 2018-03-06
  Scenarios launched: 500
  Scenarios completed: 500
  Requests completed: 50000
  RPS sent: 326.71
  Request latency:
    min: 73.3
    max: 2412.1
    median: 1460.3
    p95: 1776.8
    p99: 1962.2
  Scenario counts:
    0: 500 (100%)
  Codes:
    200: 50000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h1&gt;
  
  
  1x CPU, 1 GiB Ram
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Basic - 500 "Virtual Users", 100 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 500 -n 100 http://159.65.98.204:3000/basic
Started phase 0, duration: 10s @ 16:06:07(-0600) 2018-03-06
Report @ 16:06:17(-0600) 2018-03-06
  Scenarios launched: 499
  Scenarios completed: 0
  Requests completed: 6656
  RPS sent: 714.79
  Request latency:
    min: 64.3
    max: 734.5
    median: 357.6
    p95: 558.2
    p99: 615.7
  Codes:
    200: 6656

Report @ 16:06:27(-0600) 2018-03-06
  Scenarios launched: 1
  Scenarios completed: 0
  Requests completed: 8778
  RPS sent: 876.05
  Request latency:
    min: 499.7
    max: 868.6
    median: 575.8
    p95: 605.5
    p99: 626.5
  Codes:
    200: 8778

Report @ 16:06:37(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 8864
  RPS sent: 884.73
  Request latency:
    min: 476.5
    max: 873.3
    median: 568.8
    p95: 603.4
    p99: 615.9
  Codes:
    200: 8864

Report @ 16:06:47(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 8760
  RPS sent: 874.25
  Request latency:
    min: 473.4
    max: 849.6
    median: 569.5
    p95: 614.6
    p99: 633.4
  Codes:
    200: 8760

Report @ 16:06:57(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 65
  Requests completed: 8857
  RPS sent: 877.45
  Request latency:
    min: 467.9
    max: 856.4
    median: 542.4
    p95: 590
    p99: 613.9
  Codes:
    200: 8857

Report @ 16:07:07(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 435
  Requests completed: 8085
  RPS sent: 802.73
  Request latency:
    min: 63
    max: 554.6
    median: 415.7
    p95: 503
    p99: 517.4
  Codes:
    200: 8085

All virtual users finished
Summary report @ 16:07:07(-0600) 2018-03-06
  Scenarios launched: 500
  Scenarios completed: 500
  Requests completed: 50000
  RPS sent: 834.72
  Request latency:
    min: 63
    max: 873.3
    median: 552.7
    p95: 600.5
    p99: 622.7
  Scenario counts:
    0: 500 (100%)
  Codes:
    200: 50000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  Promise - 500 "Virtual Users", 100 GETs
&lt;/h2&gt;



&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;λ artillery quick --count 500 -n 100 http://159.65.98.204:3000/promise
Started phase 0, duration: 10s @ 16:08:07(-0600) 2018-03-06
Report @ 16:08:17(-0600) 2018-03-06
  Scenarios launched: 499
  Scenarios completed: 0
  Requests completed: 7403
  RPS sent: 788.61
  Request latency:
    min: 63.5
    max: 700
    median: 306.2
    p95: 516.4
    p99: 564.6
  Codes:
    200: 7403

Report @ 16:08:28(-0600) 2018-03-06
  Scenarios launched: 1
  Scenarios completed: 0
  Requests completed: 9068
  RPS sent: 904.99
  Request latency:
    min: 470.2
    max: 822.4
    median: 555.3
    p95: 593.2
    p99: 613.7
  Codes:
    200: 9068

Report @ 16:08:38(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 0
  Requests completed: 8916
  RPS sent: 893.39
  Request latency:
    min: 473.4
    max: 872.2
    median: 561.1
    p95: 603.4
    p99: 629.3
  Codes:
    200: 8916

Report @ 16:08:48(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 9
  Requests completed: 8784
  RPS sent: 875.75
  Request latency:
    min: 503.8
    max: 694.4
    median: 565.7
    p95: 645.4
    p99: 677.2
  Codes:
    200: 8784

Report @ 16:08:58(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 90
  Requests completed: 8995
  RPS sent: 888.62
  Request latency:
    min: 406.5
    max: 804.5
    median: 516.3
    p95: 569
    p99: 588.2
  Codes:
    200: 8995

Report @ 16:09:06(-0600) 2018-03-06
  Scenarios launched: 0
  Scenarios completed: 401
  Requests completed: 6834
  RPS sent: 799.25
  Request latency:
    min: 62.2
    max: 533.6
    median: 375.8
    p95: 449.2
    p99: 506.3
  Codes:
    200: 6834

All virtual users finished
Summary report @ 16:09:06(-0600) 2018-03-06
  Scenarios launched: 500
  Scenarios completed: 500
  Requests completed: 50000
  RPS sent: 855.72
  Request latency:
    min: 62.2
    max: 872.2
    median: 536.9
    p95: 598.4
    p99: 645.7
  Scenario counts:
    0: 500 (100%)
  Codes:
    200: 50000
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;




</description>
      <category>exploration</category>
      <category>opensource</category>
      <category>github</category>
      <category>node</category>
    </item>
    <item>
      <title>TED Talk: Teach girls bravery, not perfection (Reshma Saujani)</title>
      <dc:creator>Frank@theOpenSourceU.org</dc:creator>
      <pubDate>Thu, 08 Mar 2018 16:08:25 +0000</pubDate>
      <link>https://dev.to/theopensourceu/ted-talk-teach-girls-bravery-not-perfection-reshma-saujani--59ao</link>
      <guid>https://dev.to/theopensourceu/ted-talk-teach-girls-bravery-not-perfection-reshma-saujani--59ao</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2018%2F03%2Fted-logo-fb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2018%2F03%2Fted-logo-fb.png" alt="TED Talk: Teach girls bravery, not perfection (Reshma Saujani)" width="800" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have a daughter (as well as a beautiful wife) and this topic is of great relevance to me. Not just at home but work, tech - just life. Sometimes, when executing an idea or project (school or work), we must open ourselves up to criticism and that can be scary.&lt;/p&gt;

&lt;p&gt;Let's teach girls to be brave in the face of criticism and resistance. Our girls and women have great ideas and contributions to make and they should be willing and free to do and share them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Happy International Women's day 2018&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://theopensourceu.org/ted-talk-teach-girls-bravery-not-perfection-reshma-saujani/" rel="noopener noreferrer"&gt;Video belongs here&lt;/a&gt;: &lt;a href="https://theopensourceu.org/ted-talk-teach-girls-bravery-not-perfection-reshma-saujani/" rel="noopener noreferrer"&gt;https://theopensourceu.org/ted-talk-teach-girls-bravery-not-perfection-reshma-saujani/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>news</category>
      <category>reference</category>
      <category>linkbook</category>
    </item>
    <item>
      <title>Concept: High Performance web server w/ Promises</title>
      <dc:creator>Frank@theOpenSourceU.org</dc:creator>
      <pubDate>Mon, 05 Feb 2018 21:12:25 +0000</pubDate>
      <link>https://dev.to/theopensourceu/concept-high-performance-web-server-w-promises-kb1</link>
      <guid>https://dev.to/theopensourceu/concept-high-performance-web-server-w-promises-kb1</guid>
      <description>&lt;h2&gt;
  
  
  Purpose
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2018%2F02%2Fwebserver-promise.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2018%2F02%2Fwebserver-promise.png" alt="Concept: High Performance web server w/ Promises"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;My intended purpose is to provide a higher level of throughput -- service more requests per second through an &lt;em&gt;async API&lt;/em&gt;. It is expected that the time to service each request would increase but that is fine if we handle more requests per second. &lt;em&gt;Or&lt;/em&gt; if nothing else, at least handle more requests before issues start to occur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Concept Overview - &lt;em&gt;How?&lt;/em&gt;
&lt;/h2&gt;

&lt;p&gt;The high-level idea is for an http server running on Express + Node. From there, any incoming request is wrapped in a promise and the promise resolves to respond to the request. Of course, if throughout processing the request, other async processing is needed, other &lt;code&gt;then&lt;/code&gt;-ables can be used.&lt;/p&gt;

&lt;p&gt;For example, this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* GET home page. */
router.get('/', function(req, res, next) {
    debug("GET /");
    res.render('site/index', { title: 'The Open Source U' });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Becomes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* GET home page. */
router.get('/', function(req, res, next) {
  new Promise(function() {
    debug("GET /");
    return { title: 'The Open Source U' }; //calculation or object
  })
  .then(function(payload) {
    res.render('site/index', payload)
  });
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is regardless of need. So, I intentionally have no async operation but still use a promise; this accurately represents my idea.&lt;/p&gt;

&lt;h2&gt;
  
  
  Result: Ineffective
&lt;/h2&gt;

&lt;p&gt;I quickly did a proof of concept... which showed that this doesn't help. In fact, it made performance worse. In considering &lt;em&gt;why&lt;/em&gt;, I suspect the cost to service the promise (memory and processing) is more costly than simply responding to the http request.&lt;/p&gt;

&lt;p&gt;This is not to say a promise should be avoided in the &lt;code&gt;http&lt;/code&gt; request/response cycle but it should, instead, be used at async appropriate times. Regardless, we've learned something here and I thought it was worth sharing.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Success is not final, failure is not fatal: it is the courage to continue that counts. &lt;em&gt;Winston Churchill&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;I am disappointed this didn't have even a neutral effect on performance, let alone a negative one but it is what it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  Update (new article coming)
&lt;/h2&gt;

&lt;p&gt;Because of a comment on &lt;a href="https://dev.to/theopensourceu/concept-high-performance-web-server-w-promises-kb1"&gt;Dev.to (here)&lt;/a&gt;, I've revisited this. The commenter pointed out a mistake I made in the code I posted. That code was an example and not 1:1 from the original test code (which I ran from a &lt;a href="https://www.linode.com/?r=348bfde802d0569573c9d64dea875c1c39519950" rel="noopener noreferrer"&gt;Linode server&lt;/a&gt;). &lt;/p&gt;

&lt;p&gt;I've posted my test code here: &lt;a href="https://github.com/TheOpenSourceU/tOSU-PromiseWebServer-Experiment" rel="noopener noreferrer"&gt;https://github.com/TheOpenSourceU/tOSU-PromiseWebServer-Experiment&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;I should have done this in the first place. &lt;/p&gt;

</description>
      <category>node</category>
      <category>softwareengineering</category>
      <category>exploration</category>
    </item>
    <item>
      <title>Programmer vs Software Engineer</title>
      <dc:creator>Frank@theOpenSourceU.org</dc:creator>
      <pubDate>Mon, 13 Nov 2017 19:12:30 +0000</pubDate>
      <link>https://dev.to/theopensourceu/programmer-vs-software-engineer-2114</link>
      <guid>https://dev.to/theopensourceu/programmer-vs-software-engineer-2114</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2017%2F11%2Fcodeproject2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2017%2F11%2Fcodeproject2.png" alt="Programmer vs Software Engineer"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I came across &lt;a href="https://www.codeproject.com/Lounge.aspx?msg=5452512#xx5452512xx" rel="noopener noreferrer"&gt;this thread&lt;/a&gt; via the &lt;a href="https://www.codeproject.com/" rel="noopener noreferrer"&gt;CodeProject&lt;/a&gt; Daily News. The original forum post reads:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I continually have to check the details of syntax and stuff when programming. Things like print format specifiers, the syntax of things I haven't used for a year or so, and use a calculator to work out bit masks and check my bitwise logic. I can never get it right in my head.&lt;/p&gt;

&lt;p&gt;I don't remember details. I don't pride myself on that. I spend my time and energy on the big picture. Designing and understanding complex mechanisms. The architecture. The guts of the machine.&lt;/p&gt;

&lt;p&gt;So I think of myself as a software engineer, not a programmer.&lt;/p&gt;

&lt;p&gt;How about you lot?&lt;/p&gt;

&lt;p&gt;-- &lt;a href="https://www.codeproject.com/script/Membership/View.aspx?mid=8013439" rel="noopener noreferrer"&gt;Munchies_Matt&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This is a topic I see pop up once in a while... In some instances, even going as far as saying "software engineering isn't real engineering". (Though this isn't a case of that.)&lt;/p&gt;

&lt;p&gt;Anyway, for posterity, I'd like to put forth my definition.&lt;/p&gt;

&lt;p&gt;A software engineer is an individual that carefully considers and crafts the composition of the software... perhaps even the whole system, whereas a programmer, by contrast, is focused on individual feature(s), routines, functions or classes.&lt;/p&gt;

&lt;p&gt;In my observation of real-world scenarios, (various commercial and open source projects) a programmer (&lt;em&gt;by my definition&lt;/em&gt;) will achieve a given goal efficiently (both time and lines of code) but without regard to component composition or the relationship of the components among the whole system.&lt;/p&gt;

</description>
      <category>softwareengineering</category>
      <category>ossconcepts</category>
      <category>computerscience</category>
      <category>reference</category>
    </item>
    <item>
      <title>Concepts to Implementations: Promise</title>
      <dc:creator>Frank@theOpenSourceU.org</dc:creator>
      <pubDate>Thu, 06 Jul 2017 19:23:28 +0000</pubDate>
      <link>https://dev.to/theopensourceu/concepts-to-implementations-promise-46d8</link>
      <guid>https://dev.to/theopensourceu/concepts-to-implementations-promise-46d8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2017%2F08%2FScreen-Shot-2017-08-23-at-9.23.31-PM.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2017%2F08%2FScreen-Shot-2017-08-23-at-9.23.31-PM.png" alt="Concepts to Implementations: Promise"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Promise object represents the eventual completion (or failure) of an asynchronous operation and its resulting value.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;-MDN&lt;/p&gt;

&lt;p&gt;Put simply&lt;sup&gt;[1]&lt;/sup&gt;, it is a means to reorganize asynchronous (concurrently executing) code to reduce nesting among other reasons.&lt;/p&gt;

&lt;p&gt;Over the next couple of posts, I'm going to give a brief primer on what a promise is and how to use it but the &lt;strong&gt;main purpose&lt;/strong&gt; of this article is to understand how a Promise library is implemented. I was poking through the source code of &lt;a href="https://github.com/floatdrop/pinkie" rel="noopener noreferrer"&gt;Pinkie&lt;/a&gt; not too long ago and it seemed like a great article candidate.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://theopensourceu.org/concepts-to-implementations-promise/#whyuseone" rel="noopener noreferrer"&gt;Why use one?&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Without going into too much detail, they are used to avoid "&lt;a href="http://callbackhell.com/" rel="noopener noreferrer"&gt;Callback Hell&lt;/a&gt;" as well as create a more familiar code-flow (the &lt;code&gt;try/catch&lt;/code&gt;). pattern. Here's a contrived but pseudo real-world example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// require statements omitted for readability and brevity.
function processData( startingData, cbResult ) {
  //
  // Do something with startingData and ultimatly set result to finalizedResult.
  // ...
  var finalizedResult = startingData;
  cbResult(finalizedResult);
} 

function parentMethod() {
  fs.readFile('/my/made/up/file.txt', function callback1(err, data) {
    if(err) throw err;
    processData( data, function callback2(results) {
      sendResultToServer(result, function callback3(response) {
        executionOrderGetsConfusing(response);
      });
    });
  });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A promise allows us to restructure the code as such as this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//
// require statements omitted for readability and brevity.
var readFile = Promise.promisify(require("fs").readFile); //See http://bluebirdjs.com/docs/api/promise.promisify.html

function processData( startData ) {
  //Return a promise which impl will use "then" to implement what was "cbResult"
  return new Promise( function(resolve) {
    //
    // Do something with startingData and ultimatly set result to finalizedResult.
    // ...
    var finalizedResult = startingData;
    return finalizedResult; //Returning something makes it available in chained 'then' statements.
  } );
}

function parentMethod() {
  readFile('/my/made/up/file.txt')
    .then(function callback1(data) {    //Note that (data) =&amp;gt; {} is a newer way of defining a function in JS. 
      return processData( data );       //Not available everywhere yet though. Equiv. to function(data) {}
    })
    .then(function callback2(results) {
      return sendResultsToServer(result);
    })
    .then(function callback3(response) {
      executionOrderIsClearer(); //as well as where each method starts and ends.
    })
    .catch(function(err) {
      // Handle errors from the readFile to callback3. 
      // Like wraping the above in a try/catch
    });
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There appears to be more code in the later version because, I suppose, there is. The use of a promise doesn't reduce code. It makes the flow more obvious. And I do believe that is achieved here. You now see the order of execution more clearly. Each &lt;code&gt;then&lt;/code&gt; statement must be completed before the previous &lt;code&gt;then&lt;/code&gt; statement and should an error occur, the &lt;code&gt;catch(function(er){})&lt;/code&gt; will intercede to allow you to handle the error gracefully.&lt;/p&gt;

&lt;h2&gt;
  
  
  More examples
&lt;/h2&gt;

&lt;p&gt;Promises in JavaScript has become quite ubiquitous. Should you want to see more examples or practical uses of Promises, the &lt;a href="https://github.com/vitaly-t/pg-promise" rel="noopener noreferrer"&gt;pg-promise library&lt;/a&gt; has excellent up-to-date examples that are both clear and real-world. The library itself is a PostgreSQL interface for Node.&lt;/p&gt;

&lt;h3&gt;
  
  
  Next
&lt;/h3&gt;

&lt;p&gt;In the next post, we'll look at how promise libraries are implemented by dissecting the implementation by Floatdrop called Pinkie. A small ES2015 Promise implementation.&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;An Oversimplification but suitable for our purposes. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>exploration</category>
      <category>opensource</category>
      <category>softwareengineering</category>
    </item>
    <item>
      <title>Bit Masks</title>
      <dc:creator>Frank@theOpenSourceU.org</dc:creator>
      <pubDate>Sun, 26 Mar 2017 19:44:19 +0000</pubDate>
      <link>https://dev.to/theopensourceu/bit-masks-1omp</link>
      <guid>https://dev.to/theopensourceu/bit-masks-1omp</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2017%2F08%2Fbinary-code-475664_1280.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2017%2F08%2Fbinary-code-475664_1280.jpg" alt="Bit Masks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Bit masks are a computer science concept; in a nutshell, they represent options which can be combined in a variety of ways.&lt;/p&gt;

&lt;p&gt;A very basic example colors. Blue and Green combined create yellow. This can be represented in &lt;em&gt;bit masks&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The following example is sourced from the &lt;a href="https://en.wikipedia.org/wiki/Bit_field" rel="noopener noreferrer"&gt;Bit field article on Wikipedia&lt;/a&gt;; it illustrates the concept well for those new to it.&lt;/p&gt;

&lt;p&gt;Consider the following&lt;sup&gt;[1]&lt;/sup&gt; and take note of the binary version which is in the comment.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// primary colors
#define BLUE 4 /* 100 */
#define GREEN 2 /* 010 */
#define RED 1 /* 001 */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates the base options. The next example uses the above to further define more colors without assigning them specific numbers, although they would output as numbers.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// mixed colors
#define BLACK 0 /* 000 */
#define YELLOW (RED | GREEN) /* 011 */
#define MAGENTA (RED | BLUE) /* 101 */
#define CYAN (GREEN | BLUE) /* 110 */
#define WHITE (RED | GREEN | BLUE) /* 111 */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that &lt;code&gt;WHITE&lt;/code&gt; is all the colors -- all the bits are "on" and black is no color -- all the bits are off.&lt;/p&gt;

&lt;p&gt;I've seen this used quite a bit although, I must admit, I don't come across it quite as often as I used to. Rest assured, it is still in use and is quite useful.&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;The code presented is Pseudocode. It is not intended to be complete. ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>opensource</category>
      <category>ossconcepts</category>
      <category>computerscience</category>
      <category>reference</category>
    </item>
    <item>
      <title>Bouncy - Open Source Code Exploration</title>
      <dc:creator>Frank@theOpenSourceU.org</dc:creator>
      <pubDate>Sat, 18 Mar 2017 18:09:01 +0000</pubDate>
      <link>https://dev.to/theopensourceu/bouncy---open-source-code-exploration-3ain</link>
      <guid>https://dev.to/theopensourceu/bouncy---open-source-code-exploration-3ain</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2017%2F08%2Fcode-2620118_1280.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Ftheopensourceu.org%2Fcontent%2Fimages%2F2017%2F08%2Fcode-2620118_1280.jpg" alt="Bouncy - Open Source Code Exploration"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/substack/bouncy" rel="noopener noreferrer"&gt;Bouncy&lt;/a&gt; is a tool to "pipe raw http traffic from [an] incoming http request to a another remote end point."&lt;/p&gt;

&lt;p&gt;It's an interesting tool and, for me, a useful find. Not to reveal too much but this site is running on &lt;a href="https://nodejs.org/" rel="noopener noreferrer"&gt;Node&lt;/a&gt; among other technologies.&lt;/p&gt;

&lt;p&gt;I think this tool has a lot of possible applications&lt;sup&gt;[1]&lt;/sup&gt; but for me, it acts as a &lt;a href="https://en.wikipedia.org/wiki/Virtual_hosting" rel="noopener noreferrer"&gt;virtual host&lt;/a&gt; router. I don't want to go into too much detail here (you can see &lt;a href="https://en.wikipedia.org/wiki/Virtual_hosting" rel="noopener noreferrer"&gt;here&lt;/a&gt; for more info) but in my scenario, I wanted to setup my server so that I could host another site on the same server if needed or desired.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/substack/bouncy" rel="noopener noreferrer"&gt;Bouncy&lt;/a&gt; allows me to do that; using bouncy I created a small custom program that listens on port 80 (the website port). When it accepts an incoming request it routes it to the correct site which is running on another port (on the same server) -- say 8000 for discussion.&lt;/p&gt;

&lt;p&gt;It determines the site via the request host headers (&lt;code&gt;req.headers.host&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Summary of example configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bouncy = Port 80&lt;/li&gt;
&lt;li&gt;The Open Source U = Port 8000&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Possible&lt;/em&gt; future sites = Port 8001, 8002, etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's a small library (it's available as a CLI tool as well) and I think it's an excellent candidate for a first article. I'm, frankly, curious how it works and it's small enough to sort out the structure of these posts.&lt;/p&gt;

&lt;p&gt;For the purpose of this article, I've forked the git repository to &lt;a href="https://github.com/TheOpenSourceU/bouncy" rel="noopener noreferrer"&gt;https://github.com/TheOpenSourceU/bouncy&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll use and reference this version in this article. Because the parent/source project could continue to be developed, I've created a branch called &lt;strong&gt;&lt;a href="https://github.com/TheOpenSourceU/bouncy/tree/tOSU/explore" rel="noopener noreferrer"&gt;tOSU/explore&lt;/a&gt;&lt;/strong&gt;. This will remain consistent with this article whereas master can deviate. I want to keep master consistent with the sources' master.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technology Prerequisites
&lt;/h2&gt;

&lt;p&gt;I'll do my best to link or explain related technologies and concepts. A principle goal of this site is to engage folks with a diverse backgrounds and experience levels.&lt;/p&gt;

&lt;p&gt;That said, I do make some assumptions about a basic familiarity with some technology. At this time, I don't have public comments on this site but should you need to provide critical (respectful) feedback or ask questions, please feel use the &lt;a href="https://github.com/TheOpenSourceU/TheOpenSourceU.github.io/issues" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; issues &lt;a href="https://github.com/TheOpenSourceU/TheOpenSourceU.github.io/issues" rel="noopener noreferrer"&gt;located here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Index of Dependencies
&lt;/h2&gt;

&lt;p&gt;Knowing and understanding the high-level purpose of a package/programs dependencies is helpful in understanding the parent application.&lt;/p&gt;

&lt;p&gt;Bouncy has two main dependencies (for those unfamiliar, this is in the &lt;a href="https://github.com/TheOpenSourceU/bouncy/blob/tOSU/explore/package.json" rel="noopener noreferrer"&gt;&lt;code&gt;package.json&lt;/code&gt;&lt;/a&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ...
"dependencies" : {
 "through": "~2.3.4",
 "optimist": "~0.3.5"
},
// ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dominictarr/through" rel="noopener noreferrer"&gt;through&lt;/a&gt;: Creates a stream that is readable and writable.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/substack/node-optimist" rel="noopener noreferrer"&gt;optimist&lt;/a&gt;: (&lt;a href="https://github.com/substack/node-optimist#deprecation-notice" rel="noopener noreferrer"&gt;deprecated&lt;/a&gt;) is a command line option parser written by the same author as Bouncy.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  index.js
&lt;/h2&gt;

&lt;p&gt;The entry point and frankly the main implementation. Bouncy is built on top of the bog standard NodeJS &lt;a href="https://nodejs.org/api/http.html" rel="noopener noreferrer"&gt;http&lt;/a&gt;/&lt;a href="https://nodejs.org/api/https.html" rel="noopener noreferrer"&gt;https&lt;/a&gt; library and in a way, simply wraps it. Given it's relationship to &lt;code&gt;http&lt;/code&gt;/&lt;code&gt;https&lt;/code&gt;, Bouncy is event driven.&lt;/p&gt;

&lt;p&gt;The correct server type is created (secure or not); then three events are assigned handlers. The first is the &lt;code&gt;connection&lt;/code&gt; &lt;em&gt;or&lt;/em&gt; &lt;code&gt;secureConnection&lt;/code&gt; event which is handled by an anonymous function which we'll call the "connection event handler". The other two events are &lt;code&gt;upgrade&lt;/code&gt; and &lt;code&gt;request&lt;/code&gt; which are both assigned &lt;code&gt;onrequest&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connection Event Handler
&lt;/h3&gt;

&lt;p&gt;This accepts the parameter &lt;code&gt;stream&lt;/code&gt;. This represents the network stream of data coming in for the request. The handler adds a property called &lt;code&gt;_bouncyStream&lt;/code&gt; which is the results of stealthBuffer().&lt;/p&gt;

&lt;p&gt;The next snippet is the nuts and bolts of the handler.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var src = stream._bouncyStream = stealthBuffer();
// ... old version work around ...
else stream.pipe(src);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At this point, &lt;code&gt;stream&lt;/code&gt; is an instance of &lt;a href="https://nodejs.org/api/net.html#net_class_net_socket" rel="noopener noreferrer"&gt;Socket&lt;/a&gt; and &lt;code&gt;src&lt;/code&gt; is an instance of &lt;a href="https://nodejs.org/api/stream.html" rel="noopener noreferrer"&gt;Stream&lt;/a&gt;. (Notice that despite the name, &lt;em&gt;stream&lt;/em&gt; is not &lt;em&gt;Stream&lt;/em&gt; -- that capital "S" is important.)&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;src&lt;/code&gt; (Stream) is piped (sent) to the Socket. This completes the set up of the connection. Now, bouncy will wait for incoming requests and through &lt;code&gt;onrequest&lt;/code&gt;, route them.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;onrequest&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;This is the main &lt;em&gt;purpose&lt;/em&gt; of Bouncy&lt;/strong&gt;. This ultimately bounces the request to another port via the &lt;code&gt;cb&lt;/code&gt; parameter as this is the user implemented code provided as a callback.&lt;/p&gt;

&lt;p&gt;Here's the &lt;a href="https://github.com/TheOpenSourceU/bouncy/tree/tOSU/explore#routejs" rel="noopener noreferrer"&gt;example&lt;/a&gt; given on the GitHub page.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;var bouncy = require('bouncy');

var server = bouncy(function (req, res, bounce) {
    if (req.headers.host === 'beep.example.com') {
        bounce(8001);
    }
    else if (req.headers.host === 'boop.example.com') {
        bounce(8002);
    }
    else {
        res.statusCode = 404;
        res.end('no such host');
    }
});
server.listen(8000);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The anonymous function passed into the &lt;code&gt;bouncy&lt;/code&gt; and is called after some setup which is mainly creating the &lt;code&gt;bounce&lt;/code&gt; method. The end user then calls &lt;code&gt;bounce&lt;/code&gt; with the appropriate port and said method &lt;code&gt;pipes&lt;/code&gt; the connection to the new path.&lt;/p&gt;

&lt;p&gt;This "bounces" the request to the new port.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;code&gt;stealthBuffer()&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;stealthBuffer()&lt;/code&gt; returns an instance of the dependency &lt;code&gt;through&lt;/code&gt;; recall this provides the means to make a stream readable and writable.&lt;/p&gt;

&lt;p&gt;This is ultimately used in the connection event handler. The bottom line is it augments the request for passing it through to the &lt;code&gt;bounce&lt;/code&gt; method in the &lt;code&gt;onrequest&lt;/code&gt; handler.&lt;/p&gt;




&lt;ol&gt;
&lt;li id="fn1"&gt;
&lt;p&gt;I'm wondering if Bouncy can be used to load balance the same site on two different instances of NodeJS. I strongly suspect it could and hope to test that soon... ↩︎&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>github</category>
      <category>opensource</category>
      <category>node</category>
      <category>exploration</category>
    </item>
  </channel>
</rss>
