Thursday, March 5, 2015

NodeJS - A Little Experiment in Load Testing and Clustering

Load Testing NodeJS on Multiple Cores

Check Out the Git Hub project HERE

Something I wanted to investigate was using Node JS on a multi core system to do CPU intensive applications under high load, so I created a project to do just that.

There are a few ways to use multiple cores in NodeJS, two of which are Cluster (part of the NodeJS API) and WebWorker Threads.

I will preface this by saying I am no NodeJS expert, this project was simply for learning on my part and there may be a better way to go about this with an NGinx set up, but I wanted to share my findings and maybe you'll find it cool too.

The Planning Stages

I started the project out with a simple NodeJS and Express server, which when called with a number in the query, would calculate and return the Fibonacci sequence for that number to simulate high CPU calculations.

My first thought was to use Web Worker Threads to spin up a thread to do work on, and just pass in the data and let it work on a background thread, but this caused issues under high load as too many threads were being spun up (I had no cap at the time) and at the start they were descoping and causing segmentation faults.

I ended up fixing the Seg Fault issue, but even so, they were burning through all of my VMs 2GB of memory and crashing.  

I attempted to create a Worker Pool function to control the amount of threads at any one time, but it quickly got quite complicated.  The idea was to use a queue and simply drop information off and process when ready, but with web requests and waiting on data, this as well got very complicated.

Then I stumbled across the Cluster section of the NodeJS API and found my solution.  With the Cluster API you can spin up multiple instances of your node server on the same port.  So I decided to test if this truly would improve my performance.

Load Testing

I installed loadtest in order to deliver high concurrency testing to my application and began to test the application.  On one branch of my git project I had the vanilla, single threaded NodeJS server which would generate a Fibonacci sequence, and on my other branch I had my project which generated 4 servers on a single port, which would use up the multiple cores.

This was a MUCH simpler solution to building a multi-threaded system within a single event loop and was extremely easy to set up.

So the load testing began.  I called out to my application like so:

loadtest -t 20 -c 32 http://localhost:3030/fib?num=25

I pinged my application using various concurrency values for 20 seconds testing periods.  I tested up from 1 concurrent connection up to 1000 connections.

While I don't believe all four cores were actually being used (as it was on a VM and my computer didn't crash) I did see quite an improvement using the multiple core approach (as one would expect).

The Results

The results from the load test are as follows.  Load test outputs the maximum response times for 50%, 90%, 95%, 99%, and the maximum response time as well as Requests Per Second, Mean response time, and Total Requests.

Computer Specs:  The VM was an Ubuntu 14 VM with 2 GB Ram, 4 processors.

Each request was made with a Fibonacci sequence of 25 for 20 seconds.

NodeJS Single Event Loop

ConcurrencyCompleted Requests50%(ms)90%(ms)95%(ms)99%(ms)Max (ms)Req / SecMean Lat (ms)
648891135169180245286429150
20081103361276135833007364405480
1000817812353726762615726162564092510

NodeJS Multi-Core with Cluster

ConcurrencyCompleted Requests50%(ms)90%(ms)95%(ms)99%(ms)Max (ms)Req / SecMean Lat (ms)
64150097015519332756075080
200144982524765677561062596330
100014923117219542538361876417181350

As you can see the results from using the multi-core approach were much better than the single event loop, and using Cluster is super easy to do.  

You can fork the GitHub project here:  https://github.com/WakeskaterX/NodeThreading

The main fork is (well master too, but) hostedVM which has the standard deployment of nodeJS and express, and the multi-core approach is on the hostedVM_multicore branch.

Feel free to test it as well and let me know how your results are with better machines than my very low powered VM.

Cheers,
WakeskaterX

Tuesday, January 27, 2015

PlayCrafting Boston Winter Expo - February 24th!

Hey All!  Exciting things have been going on the past few months, such as learning new web Technologies and taking part in GGJ 2015 and all sorts of exciting things!   But, this post isn't about that, it's about...

The PlayCrafting Boston Winter Expo!



Stop by at 6pm at the Microsoft NERD center in Cambridge on February 24th, 2015 and check out tons of awesome local indie developers and their games.

You can sign up at the event bright page here.

I'll be there showing off SBX: Invasion and giving away free game related goodies!

Sign up before Feb 23rd to get a discount and come hang out with your local indies!

-Jason C.

Sunday, November 2, 2014

Converting Visitors to Register - adding an Unobtrusive Pop Up

So after about a month or so of having my e-mail login active on my web page, I have exactly zero sign ups.  This isn't unexpected so I'm working on drawing more attention to the login and register buttons at the top.

A lot of websites see great results from using a full page popup when a new visitor visits the site, but generally when I see these I immediately leave the page, and it's fairly infuriating.

So my goals with the most recent pushes to the website were:

1.  To have a pop up that notifies new users about the registration button, but have it be off to the side and non obtrusive when viewing the website and easily closed.

2.  To make the registration process a bit more intuitive and flow a little easier.

For the first goal, I created a little speech bubble pop up that will show only if a user does not have login information saved on their computer, and when it pops up, it will only show for about ten seconds, and won't show back up for 24 hours.  I might extend this to 48 hours / a week, but I don't think users are visiting my site more than once within any length of time.

Here's an example of the pop up:



I wanted it to be mostly out of the way, and while it does cover up some buttons on the UI, it has a clear close button that closes the box immediately.

The second thing on my list was to make the registration process easier.  Before, the login and registration buttons were tied together, meaning you had to click them both and that would pop up the login prompt, then you had to click the register button, and then register.

These buttons have now been split out into a separate login and register button so that users can choose accordingly and not have to go through an extra click.

Just a few small UI updates that I've been meaning to do to convert more visitors into registered guests.  I'll post an update later on the results of the slight UI changes.


Cheers,
Jason C.

Sunday, October 5, 2014

Automated E-mail Authentication In! Also Anomaly Updated.

So I got the automated E-mailing Systems in the website.  When you register, it will generate an e-mail to the submitted e-mail with a link to authenticate the token.

Right now the token is indefinite, but I'll add in a time based token at some point.  I already laid the foundation for the time token in the database & script, but the system is fairly simple.

As you can see here, the activate.php file just takes a token, does some "very basic" checks on html chars / alphanumeric chars and then simply flips a boolean character in the database saying that this e-mail has been authenticated.



It's important to validate e-mails in this way as you want to keep a high sender reputation from your mail server.  Bounced e-mails are no bueno.

Also Anomaly has been updated to have 10 levels.  The only problem is that it's fairly easy right now because of the rule sets.  I need to add more variety to the rules and include multiple rules on the harder levels to mix things up.  Right now this will let me play around with rule sets, what is fun, what is challenging, etc and get some feedback as well.

I need to mix it up a bit so that the Anomaly is slightly better hidden on the larger levels.  Right now it becomes fairly easy to locate the Anomaly with the ruleset "Adjacent".


Please check out Anomaly and let me know what you think!  I'm always looking for feedback on this kind of stuff.

Cheers,
Jason C.

Sunday, September 28, 2014

Login Function Complete!

The Login and Registration functions are now complete!

I spent all of today porting the back end code from Java to PHP.  It took me a decent bit, but I combined some sections of the code as PHP isn't as conducive to OOP as Java, and I didn't need the modularity I had before.

The site uses some client and server side authentication so if you want to try and break it, by all means please try while my database is largely empty!

I ran into a couple bumps deploying the code tonight, the main one being that yet again, my hosting lacks a certain feature.  Namely MySQL Native Driver, so that means the functions I had built to connect to MySQL didn't work so I had to rework them all to work without the driver.

Minor stuff, but still, annoying.  I'll have to take that into account in the future as well.

However, the website and login functions are fairly secure, I still have a bunch more security to add as well, but for now I'm happy with the deployment.

The next step is using the generated internal token to authenticate e-mails by sending automated e-mails so that visitors can Opt-In to the news feed.

Exciting stuff!  I'll start work on that next weekend, so hopefully I can start authenticating e-mails automatically in the registration process.

Cheers and go register at the website!

-Jason C.

Sunday, September 21, 2014

Updated Website Deployed - but... have to rebuild the back end.

Well I deployed the new website to my HostGator web hosting account... ONLY to realize they don't offer Tomcat Apache support for my plan.

And since my back end is built in Java, that pretty much means I need to learn PHP and rebuild my entire back end.  Delightful.

All snarkiness aside, I'm glad to have the front end built out, even if rebuilding the back end is going to be a pain.  There's a lot to see on the web site, with a galactic map on the home page and 5 game pages to check out, feel free to browse and let me know what you think!


So I guess I'll be learning more PHP to get the back end up and running, but at least I know where to go from here.  It probably means I'll have to set up a WAMP stack on my home machine too which I don't currently have installed.

It's 100% my fault for not reading all the details, but I read they had Tomcat support and never bothered to do any kind of testing.

Anyway, at least the back end stuff isn't visible to the user so I can just work on that and deploy it when it's ready.


Cheers!
Jason

Thursday, September 18, 2014

Creating a Rotating Gallery - Game Page Links for new Website

So the games page was supposed to be a simple panel of images that linked to pages for each game I have created and/or worked on.  But I thought to myself, "That's Boring!" so I created my own rotating gallery page viewer that flips through all the options as you click on them.

The rotating gallery uses JQuery, Javascript and CSS3, so knowing a bit about those will help you understand what's I'm doing.

First, here are a couple screen shots of the gallery:
When you click on a panel to each side, it rotates through the selection to that panel:

It also uses CSS transitions so it has a nice easing effect as well.

For each panel, they will link to a page specifically for that game.  Right now you enter via clicking the button at the bottom but I might change the coding so that when you click on the main picture, if it is active you will go to that page.

The code is a bit long so I won't go into too much detail, but I'll highlight a few of the places of note in the script and CSS.

The Main Page:

So the goal was to just add divs as I needed and to have the JavaScript file manipulate and add the divs to a list and control them that way.

I wanted the main page to be easy to add things to and all the work to be hidden in JS.

As you can see it's pretty intuitive and makes a lot of sense what's going on.  You have 5 game pages, each with a title and an image.  I kept the actual links in the JavaScript as well, but that's something I could pull out into the HTML later if I needed to.

Styling:

The exciting thing about the rotating gallery is using CSS classes and ids with the CSS3 transitions to create neat effects just by swapping the classes and ids of the divs.  It makes putting neat transitions in your website a lot of fun and fairly easy to do.  I know this isn't new to a lot of web developers, but if you're somewhat new to web design and development, this stuff can be pretty exciting.

Let's take a look at the CSS file and see how it's doing a lot of the work for me:

You can see here, we wrap our boxes in a holder with position relative, so that we can use absolute positioning.  Also the neat work is done with the transition tags.  All it's saying is that between changes in the class to modify position, we're going to give all transitions a .5 second ease between the divs, and the browser will do all the animation work for us.  Neat!



Here we're specifying the size and dimensions of our Previous node, our Next node and our Hidden nodes.  You can think of this gallery like a linked list.  We're going to be rotating through images, and the first image will always appear after the last one and vice-versa. For this gallery I wanted to make it seem like the pages were fading away so I set the opacity to 50% and the size to 50% for the images to the side.  

You'll also see I set the Z indices up so that the main one was the highest and the next/prev ones were in between and the hidden nodes were the lowest.

Note:  It's important when you set your Z-Indices, to keep them positive if you want the divs to be clicked on.  If you don't it's likely click functions won't work because they'll be behind the main layer of the page.



So now all we have to do is link the divs together and add some click functions!

Script:


The first part of the script is the set up.  I call this to push each ID into an array for my divs and set them all up to be ready to be called by the rotate functions.  I set all the divs to invisible and hidden and add the on click functions to each of the divs (only called when visible and not the current one), so essentially only the previous and next ones can be clicked (but I could expand this out later if I wanted).  Then I call the rotate function to set up the screen properly.


The next is our rotate function.  This calls out to a few other functions that I've made, the GetPrevious and GetNext functions just check the next and previous number based on the total number and the current number (so GetPrevious(1, 5) is 5 so that we have a linked list) and then the RotateNext and RotatePrevious functions change the classes on the divs accordingly.


I'll show you a snippit of the RotateNext function so you can get an idea of what it's doing.  Basically I need to shift all relevant divs, which means, 2 before, 1 before the current and 1 after are the relevant divs, since all others will remain hidden.


Then I set the currentShow (the currentDiv, not sure why I named it that) and we're good for this rotation!  Then if our current one isn't the one we wanted to click to, it will continue to rotate until we reach our destination.

So that's a little bit about the Rotating Gallery that I made,  next steps are working on all the pages for the actual games and getting A Slight Anomaly up on it's own page as well as a playable demo, and then testing and pushing to live!  Exciting stuff.

Hopefully this weekend I can power through the game sites so that I can start prepping to push the new website live.

Subscribe to stay tuned into the updates and to learn some neat tips and tricks about web development!

Cheers,
Jason C.