big app design for node.js
DESCRIPTION
Designing the code of a large application in production and scaling up to thousands of users while doing it all in Node.js is a challenge that no developer should face alone. I will discuss how we have developed a highly decoupled, plugin-based architecture and a decentralized infrastructure for Cloud9 IDE, along with the technologies we've developed and the difficulties we faced in order to build the largest Node.js application that exists in production.TRANSCRIPT
BIGapplication
designSaturday, November 10, 12
@sergimansilla
Saturday, November 10, 12
Smart code completion
Saturday, November 10, 12
Static analysis
Saturday, November 10, 12
Free linux VM
Saturday, November 10, 12
Bring your own machineSaturday, November 10, 12
Real terminalSaturday, November 10, 12
Hundreds of thousands of lines of JavaScript
Saturday, November 10, 12
dynamic,weakly-typed
language
Saturday, November 10, 12
one single thread
Saturday, November 10, 12
Remote VM
Cloud9 datacenter
IDE serverRemote
VM
Remote VM
Openshift
Saturday, November 10, 12
Saturday, November 10, 12
Saturday, November 10, 12
Modularization
Saturday, November 10, 12
Black box coding
Saturday, November 10, 12
Saturday, November 10, 12
Good at abstracting away
require
Saturday, November 10, 12
Not that good at app-level abstraction
require
Saturday, November 10, 12
duplicated modules
maps to folder names
Relies on FSrequ
ire
hard to configure module
Saturday, November 10, 12
Dependency error handling
coding time compile time run time
KA-BO
OM!
- Server crash- Unhappy customers- Developer gets fired
Saturday, November 10, 12
How to fix it?
Static dependency list
Named services
Easy configuration
Resolve at startup
No FS required
Pass an object
Saturday, November 10, 12
Architect
github.com/c9/architect
Saturday, November 10, 12
Everything is a plugin
Plugins can consume plugins
An application is just a set of plugins
Architect
Saturday, November 10, 12
Dependency model
require
Architect
runtime
compile time
Saturday, November 10, 12
Dependency error handlingArchitect
coding time compile time run time
- Happy customers- Developer keeps job- Fails before release
Saturday, November 10, 12
github.com/sergi/nodejsconfit2012
Saturday, November 10, 12
Saturday, November 10, 12
Declare entity ‘cook’ with behavior
Use ‘cook’ to do some cooking
Saturday, November 10, 12
Cook Cooking action
Dependency model
Saturday, November 10, 12
package.json
Builds dependency tree
executing codewithout
Saturday, November 10, 12
{{
cook/package.json
do-‐cooking/package.json
Saturday, November 10, 12
Next
Extract the code
Wrap in Architect plugin code
Make two plugins
Saturday, November 10, 12
Function signature
Call when done
Saturday, November 10, 12
Architect plugin code
Module.exports
Options - we’ll talk about it later
Imports - everything you ‘consume’
Register - call when done
Saturday, November 10, 12
Saturday, November 10, 12
Saturday, November 10, 12
Easy to testMock dependencies
Saturday, November 10, 12
‘cook’ should be called 8 times
Saturday, November 10, 12
No black magic
Specify dependency model
Feed architect a config file
Call ‘createApp’
Saturday, November 10, 12
Saturday, November 10, 12
Saturday, November 10, 12
Configuration
Per-plugin options
No global options object
Specify in config file
Saturday, November 10, 12
Saturday, November 10, 12
Saturday, November 10, 12
Options
Passed in at startup
Options can be dependencies
Fail if options aren’t present
Saturday, November 10, 12
Saturday, November 10, 12
Saturday, November 10, 12
Your app as chunks of functionality
rather than sets of classes
Saturday, November 10, 12
chunks of functionality
Implicit type constraints
Keep implementation private
Swap features instead of interfaces
Saturday, November 10, 12
How does Cloud9 use it?
Open source version
Local version (OS + sync)
Hosted version
Normal
FTP
SSH
Saturday, November 10, 12
Saturday, November 10, 12
Swap feature per implementation
On OSS: talk local filesystem
On FTP: talk FTP library
On SSH: talk via a SSH bridge
Saturday, November 10, 12
Architect is a DI framework
Saturday, November 10, 12
But a quite special one
Saturday, November 10, 12
IDE instance(FTP)
IDE instance(SSH)
IDE instance(Normal)
IDE instance(Normal)
Single node.js process
Other code (dashboard etc.)
Saturday, November 10, 12
Architect can do
Multiple instances of same pluginRun independently
But in the same process
Saturday, November 10, 12
Centralized event bus
Loose coupling between plugins
No hard dependencies!
Can also do inter-context communication
Saturday, November 10, 12
Eventbus
Plugin
Other plugin
Emit event
React on event
Saturday, November 10, 12
Saturday, November 10, 12
Saturday, November 10, 12
And now scale
Swap it with i.e. Redis PubSub
Plugins will never notice
Modular awesomeness!
Saturday, November 10, 12
Modularize in feature blocks
Don’t over engineer
Don’t create too small blocks
They aren’t interfaces!
Saturday, November 10, 12
Avoid context switching
Less code!
Less errors!
Less boilerplate!
Saturday, November 10, 12
Loose coupling
Use (don’t abuse) an event bus
Smaller dependency graph
Saturday, November 10, 12
Happy coding!
Saturday, November 10, 12