Generative AI for Technical Writer or Information Developers
What is NodeJS - Why Should You Care
1. NODEJS
WHAT IS IT
AND
WHY YOU SHOULD
CARE
Who here as used Node before?
Who here feels like they don’t understand why its so cool, or don't see the big deal?
3. NON-BLOCKING IO
NODE<?>
TOOLS
if you have heard about node, you probably have heard about this non-blocking io craze..... we will spend a good bit of time grasping this...
It is very important to understand how a PURELY evented system works whether; your just using frameworks and even more so if you want to get involved and build
libraries.
once we get all that down, we will look into what the world node is.... yes the lack of “.JS” is intentional... you will see...
we will wrap up looking at tools to make building apps a little more comfy for us.
4. “IO needs to be done differently, we are doing it wrong.”
-Ryan Dahl
result = lib.select('from network')
ryan dahl, the creator of node... he is very opinionated about how nonblocking io should.
lets break down that snippet.... its very familar to us all....
but think about it, what is our cpu doing while the query is processing across the network....
its just ignoring everyone else; waisting precious cpu cycles... thats pretty dumb huh?
yes, we have “ways” around it, which I will dig into next... but why is this such a big deal? Your response times are quick enough right?
well.... the web is changing... there is no arguing this.... gone are the days of request/response.... and ajax will slowly follow it.
we already have rich flash/flex clients, mobile apps, and modern browsers able to keep persistence connections open.
does your app have 10,000 yours? can your server keep 10,000 concurrent connections PERSISTED.
this is definitely something you need to be thinking about.....
5. THE RESTAURANT
I can’t remember where I first heard the example of an event loop as an doctors office, but thank you... this is inspired by that.
So lets take a look at why your server might be holding you up from building that real time app you want!
I have seen couple very educational intros for this same topic, i can’t remember where I saw them, but thank you and here is my own twist on it....
Lets think about your web stack as a unique little restaurant setup... You have a kitchen (your data store), waiters/waitresses (your web server) and of course customers
(web requests).
6. BLOCKING - PROCESSES
CUSTOMERS
WAIT
WAITER
1. 2. 3.
KITCHEN
This is where we started a while back, a single process serving requests. In our restaurant world; that is like a waiter serving a single customer at a time until they
completely finish eating and leave before moving on to the next customer; They just sit there and WAIT!
Well that sucks!
In order to for our restaurant to make it, paralyze this model... So we buy a waiter per customer.... However, obviously this will only go so far until ran out of operational
resources.
This directly correlates to the cpu world. Processes are expensive operations and you can only spawn so many until your server is out of resources.
7. UH OH.
Yeah... that doesn’t work very well.... Unless you are okay with declining requests to your application. :-)
So let’s look at the next solutions....
8. BLOCKING - THREADS
CUSTOMERS
WAIT
WAIT WAIT
MANAGER RUNNER PER CUSTOMER
STAND BY
KITCHEN
So our restaurant is about to tank due to resources constraint, we fired the last person with their crazy waiter per customer concept and hired a new one who promises that
he can serve many more customers. They plan to accomplish by employing many waiters who are not to experienced, so that they cost less. He will be keeping one
experienced employee to direct them around. However each waiter will still be dedicated to a customer, but since they are cheap it will work out okay.
You might have guessed this is the concept threads. (give or take)
So we stick with this for a while and are happy; It works pretty decent.... but after growing a bit it was not too long till the complaints started piling up about customers
getting receiving incorrect food, bills, drinks, etc.
Hmm... It appears our pool of inexperienced waiters are getting all out of sync... On top of that we are running out of resources to keep adding more of them; they might be
cheap, but they add up!
9. UH OH!
So back to cpu world... you might have also guessed the problem here is that we didn’t properly design our system with the correct synchronization and locking algorithms
that are required in a multi-threaded environment. Also, yes threads are light weight, but what your cpu has to do to maintain them as far as managing all the call stacks
and context switches is very expensive and error prone. I will not argue that you cannot build a scalable system this way, the biggest applications in the world run this way;
However, unless you are an expert in this area, your system will be buggy and will not scale as you hoped. We need something simple; something that will allow “less than
expert programmers to create scalable systems.”
10. class Lock extends Object import Lock; public interface Executor {
{ void execute(Runnable command);
private boolean m_bLocked = false; public class CriticalResourceUsingSynchronizedAndLocks
}
{ int NTHREADS = 100;
public synchronized void lock() private Integer m_readLock = new Integer(0); exec = Executors.newFixedThreadPool(NTHREADS);
Executor
{ private int m_reading = 0; while (true) {
private Lock m_writeLock = new Lock();
// if some other thread locked this object then we need to wait request = acceptRequest();
// until they release the lock Runnable requestHandler = new Runnable() {
if( m_bLocked ) public int read() public void run() {
{ { handleRequest(request);
do int readData = 0; }
{ };
try // lock readers exec.execute(requestHandler);
{ synchronized( m_readLock ) }
{
// this releases the synchronized that we are in List<Runnable> shutdownNow();
// then waits for a notify to be called if we are the first reader lock writers
// in this object
// then does a synchronized again before continuing boolean isShutdown();
wait(); if( m_reading == 0 )
} // lock the writers boolean isTerminated();
catch( InterruptedException e ) m_writeLock.lock();
{ boolean awaitTermination(long timeout, TimeUnit unit)
e.printStackTrace(); // increment semephore throws InterruptedException;
} m_reading++;
catch( Exception e ) <T> Future<T> submit(Callable<T> task);
{ } // unlock readers
e.printStackTrace(); <T> Future<T> submit(Runnable task, T result);
} // do read (may take significant time...)
} while( m_bLocked ); // we can't leave until we got the lock, which Future<?> submit(Runnable task);
// lock readers
// we may not have got if an exception occured
} synchronized( m_readLock ) <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks)
{ throws InterruptedException;
m_bLocked = true; // decrement semaphore
} m_reading--; <T> List<Future<T>> invokeAll(Collection<Callable<T>> tasks,
long timeout, TimeUnit unit)
public synchronized boolean lock( long milliSeconds ) if( m_reading == 0 ) throws InterruptedException;
{ // release the writers
if( m_bLocked ) m_writeLock.releaseLock(); <T> T invokeAny(Collection<Callable<T>> tasks)
{ throws InterruptedException, ExecutionException;
try }// unlock readers
{ <T> T invokeAny(Collection<Callable<T>> tasks,
wait( milliSeconds ); // return read value long timeout, TimeUnit unit)
} return readData; throws InterruptedException, ExecutionException, TimeoutExce
catch( InterruptedException e ) }
{ }
e.printStackTrace(); public void write( int x ) doWork() {
} { ExecutorService exec = ...;
// lock writers while (!exec.isShutdown()) {
if( m_bLocked ) m_writeLock.lock(); try {
{ Request request = acceptRequest();
return false; // do writing exec.execute(new Runnable() {
} public void run() { handleRequest(conn); }
} // release writers });
m_writeLock.releaseLock(); } catch (RejectedExecutionException e) {
m_bLocked = true; } e.printStackTrace();
return true; } }
} }
}
public synchronized boolean lock( long milliSeconds, int nanoSeconds )
{ public void stop() { exec.shutdown(); }
if( m_bLocked )
{ void handleRequest(Request request) {
try if (isShutdownRequest(req))
{ stop();
wait( milliSeconds, nanoSeconds ); else
} handle(req);
catch( InterruptedException e ) }
Uhhhhhhhhhhhhhhhh?!?!?!?!
{
e.printStackTrace();
}
if( m_bLocked )
{
return false;
}
}
m_bLocked = true;
return true;
}
public synchronized void releaseLock()
{
if( m_bLocked )
{
m_bLocked = false;
notify();
}
}
12. NON-BLOCKING
CUSTOMERS
ORDER
WAITER
READY
RUNNER
KITCHEN
So we fired the last guy (we got scared after he started rambling on about syncs, locks and executors)...
Now we have found someone new that says he can solve our problem with 2 smart waiters. Hmm... this sounds a little to familiar that customer to waiter deal... But hey
what the hell!
So whats the grand idea?
We put one waiter up front, he is quick and does not wait with each customer after taking the order. He just take the order, passes it off the a friend in the middle and
moves on. On top of that, after he has quickly processed all the customers, he clocks out because he has no more works to. In fact he takes a nap!
So the friend in the middle is bit mysterious, we don’t know how he works.. nor do we really care... We just know that he notifies the customer level waiter whenever food is
ready. He also clocks out when there are no more orders to process.
So wow, our restaurant is serving 10x customers with 25% of the operating cost. Even though we are running fine, since we have all this extra space by not having so many
of those unexpiranced waiters sitting around, we could actually duplicate this operation and serve even more within the same space!
13. YAY! WIN!
AWESOME!
This is how nonblocking IO works. Our application takes in requests and passes off a callback of some sorts to an event loop which will be fired when its ready; mean while
our application just keeps taking in requests, even though the one before him is not done yet.
The side number about the waiters going to sleep has merit too; within the nonblocking paradigm, if there are no more requests to be served, but the callbacks are still
pending, our cpu idles out. This is a good thing.
Last but not least, our application, while quick, it cannot be at two tables at the EXACT same moment in time... since there is only one of them, there is no getting
resources out of sync. Yes, that means there is no need for synchronizing, locks, etc. It’s completely race condition safe.
So wow, this is simple and it scales... This is a dream.
14. NON-BLOCKING IO
NODE <?>
TOOLS
Now we have nonblocking IO down, we are experts! However we need a platform right?
15. <YOUR PLATFORM HERE?> = WRONG!
Python? Ruby? Lua? Etc???
The issue is while you can certainly build an event loop in another language, your platform as a whole will not blend well with the event loop. For example, lets say you are
taking in web requests in a nonblocking manner, for each request you now need: 1) check the cache server, if its there stop here of course. 2) check the database server. 3)
cache the result to our cache servers. 4) log all this to the logging server.
You will probably use an existing driver for all 4 of those operations. This driver is blocking.... it was not designed for nonblocking. We just put at best 1 blocking call and
at worst 4 blocking network calls. This will completely circumvent any benefit gained from the nonblocking requests.
16. UH OH!
It will not work. We need a completely new platform with no “extra baggage” per say.
17. FUNCTIONAL
CALLBACKS
ASYNC
EVENTS
We need a language with the following features in order to fit will into the event loop layer.
Hmmm.... sounds familiar, No?
18. $(document).ready(function() {
$('#foo').bind('click', function(event) {
$.get('/resource/', function(data) {
});
});
});
We all know this right? This is completely nonblocking.
19. NON-BLOCKING IO
NODEJS
TOOLS
nonblocking systems and javascript are a match made in heaven.
1) JS has the concept of events, callbacks, etc baked INTO the language.
2) JS has no “extra baggage” on the server.
This is what node is! Its a server side JS platform with a complete set of system level bindings that do all its IO operations within the event loop. The event loop is a
language level construct now, not some add on. We can accomplish amazing performance this way.
20. EVENTS
STREAMS
FS
UNIX SOCKETS
HTTP
TCP
UDP
DNS
...
A complete library for all system level programming. Its everything you see in your normal language, plus tons of goodies for creating servers because node is geared
towards network programming.
21. EVENTS BUILT INTO THE LANGUAGE, YOU
HAVE TO WORK HARD TO BLOCK THE PROCESS.
NO HISTORY = AN ENTIRE NONBLOCKING
PLATFORM.
Nothing blocks.
23. HTTP
GIST
Lets make a simple hello world http server that will make apache run scared.
24. MODULES
GIST
Modules are how we organize our code... its a bit different than many scripting languages... not just an include of source code....
It returns an actual object.
Let’s wright some modules....
26. NPM NODE PACKAGE MANAGER
NPM is the ecosystem, its like rpm, gems, brew, etc. It has all the tools you will need.
Let’s install some modules and build up some dependencies....
27. BUILD SOMETHING
GIST
Lets build something fun....
It will: grab #ncdevcon from the twitter steam api, push it out to command line net clients over tcp and also to a web page via websockets. Easy right?
I don’t really get the twitter api, so it doesn’t grab every hash tag.. but it works for now :-)
28. WINDOWS?
V0.5.X - UNSTABLE
Windows is being worked on in the 0.5.x series. Its pretty much all they are focusing on, they are taking it very seriously and last I heard they were able to get a http server
on windows to run just as well as linux. They are not compromising anything... which will be great for the windows crowd.
29. IN CLOSING
USE STABLE - BE SMART
KEEP YOUR CODE DECOUPLED - API CHANGES
EMBRACE NPM - USE FRAMEWORKS
PROCESS MONITORING
EXCEPTIONS
1) Don’t use the latest because its there. Use stable branch. Right now that means v0.4.x
2) Things change in node from time to time, not so much as it used to, but make sure your code is maintainable and can handle change. (not that you shouldn’t be doing
that anyways!)
3) Embrace NPM. You don’t need to write http servers by hand. Use a framework.
4) Use a process monitor to kick your app back up if it dies. (forever, monit, upstart)
5) Exceptions suck... A side effect of the effect loop is no huge stack, therefore no huge stacktrace for debugging. Might be better in v0.6.x
30. LINKS
NODE
NPM
GOOD EBOOK
WINDOWS
NODE KNOCKOUT
ECMA 5 FEATURES
Good links to use....
31. QUESTIONS?
THANKS FOR LISTENING!
TWITTER: GJOHNSON391
Thanks!