Upload
mark-trostler
View
1.474
Download
0
Tags:
Embed Size (px)
DESCRIPTION
Exploiting Multi-Process Architectures using JavaScript
Citation preview
Motivation
Write programs that do one thing and do it well. Write programs to work together. Write programs to handle text streams, because that is a universal interface.
Controlling complexity is the essence of computer programming
The only way to write complex software that won't fall on its face is to hold its global complexity down — to build it out of simple parts connected by well-defined interfaces, so that most problems are local and you can have some hope of upgrading a part without breaking the whole.
The Goal Bite sized
Text-based communication
Independent
KISS
Naturally private methods
Naturally loosely coupled
Fail gracefully
Maximize processor
Code Complexity
#1 indicator of bugs: code size ( > 9300 chars)
In the eye of the beholder: the Co-Worker Test
Dependency count - coupling
Dependencies
Required for object operation
Lots of dependencies make code complex
Long chains of dependencies make code complex
More code loaded locally – more chance for something to go wrong
* Load JS, ‘require’
Minimize Dependencies!
Coupling
What do you do with a dependency?? Instantiate it? Call methods? Access properties? Change shared global state? Alter all of them (prototype)?
Keep Coupling Loose!
Application?Applications are message passing systems with a bag of objects in the middle with input and output at either ends.
Object3
Object2
Object1
Current Application Paradigms
Method based APIs Tight coupling adds complexity
Remote interfaces Non-local – sync or async Local interface to remote object (Model)
Object-based callbacks Eventing/Callbacks require dependent object to
be local
Current: Method-based API
Current: Method-based API
Maximizes coupling
Easy to add dependencies
Synchronous across objects (typically) – blocks caller
Local
Understood
Method / Event Hybrid
Local reference to object
Synchronous emitter
Asynchronous listener
Same process / memory space
Same coupling
Same dependencies
Pure Event API
Local reference
Same dependency / Same coupling
Return values?
Semantics?
Not as understood
Something still wrong…
A Different App Paradigm
Pure Event with Hub
Asynchronous emitter
Asynchronous listener
NO local reference
Shared nothing
Loose coupling
Function callbacks
Central Hub
Independent modules cannot find each other
All connect to central hub
Hub unicast/broadcast events/responses
Session handling
Authorization services
Event registration
No local references
Services run anywhere (no same-domain)
What Does It Look Like?
Listeners on event name, get an object and an optional callback
Emitters send event name, data object and an optional callback
Callback function expects (error, response) where error is either an object or string or null and response is an object (NodeJS standard)
Emitter
hub.fire('user:getProfile', function(err, userObject) {
if (!err) {
Y.one(‘#user’).set(‘innerHTML’, JSON.parse(userObject));
} else {
hub.fire(‘ui:error’, { msg: err} );
}
});
Emitter / Listener hub.on('user:getProfile', function(obj, callback) {
hub.emit('session:get', { 'eventHub:session': obj['eventHub:session'] }, function(err, session) {
if (err) {
callback(err);
} else {
redis.hgetall('user:' + session.user, callback);
}
});
});
Listener var redis = require('redis').createClient();
hub.on('session:get', function(obj, callback) {
var session = obj['eventHub:session'];
if (session) {
redis.hgetall('session:' + session, callback);
} else {
callback('No session');
}
});
Typical Web Server/App
HTTP Serve
r
Controller / Router
Session
Models
Authentication
Authorization
ThreadingStatic content
DB connectors
540+ apache modules
Servlet container
Sink/Source ALL communication
Browser
Webserver??
HTTP server is just a module
Serves only static content
No entangled business logic
No entangled routes
Do not need to restart on changes to other modules
EventHub Architecture
Event Hub
HTTP Server
Session
DB
Browser View
Browser
Module
User Module
Unicast and Broadbast
Both kinds!
Event sent to one listener or many
Still must register for the event for broadcast!
Hub can return error if no one is listening
Module
Event Hub
Module NEW
UNICAST REGISTER
EVENT FLOW
UNICAST REGISTER
DONE EVENT
FINAL FLOW / SHUTDOWN
EVENT FLOW
No Dropped Events
Wither MVC?
Processes vs. Threads
PROCESSES EASY
• IPC handled by hub
• Independent modules
• Deterministic• Straightforward
testing• DB ACID
THREADS HARD
• Non-deterministic• Synchronization
issues• Deadlock• Testing dicey• Syntactic cruft
Performance
Methods
• FASTer• synchronous
Events
• SLOWer• asynchronou
s
Scaling Web Apps
Webservers behind VIPs / load balacners
Load balancers affinity / sticky sessions
Serialize session data
Scaling Event-based Apps
Multiple hubs with replicated modules
Clients specify hub – dynamic or static
Broadcast events – bring up more modules
Complexity
Method
• Dependencies• Straightforwar
d• Internal
complexity• Bigger pieces
Event
• Self-contained• More moving
pieces• External
complexity• Smaller pieces
Testability
Methods
• Coupled dependencies
• Threads Non-deterministic
Events
• Isolatable• Loosely
coupled• Processes
deterministic
Deploy
Method
• Big Bang• No
incremental changes
• Simple
Events
• Only incremental changes
• Complex
Third Party Options
Method
• Import locally
• Hosted remotely
• Loaded locally
Event Hub
• Import locally
• Hosted remotely
• Global hosted remotely
• Not Loaded!
FAILURE
Monolithic systems fail completely
Event-based systems fail incrementally Can route around failure Degrade gracefully
The Goal
Bite sized
Text-based communication
Independent
KISS
Naturally private
Naturally loosely coupled
Fail gracefully
Solves World Hunger?
Theories
Actor Model
Hypervisors
Microkernels
Event hub analogy: Ethernet Hubs Switches Router
EventHub
Built on socket.io
Hub serves JS
Server clients NodeJS
Browser clients YUI jQuery
Practices
EventHub https://github.com/zzo/EventHub
Korus http://code.google.com/p/korus/
Akka http://akka.io
Netty http://www.jboss.org/netty/
Minix 3.2 http://www.minix3.org/
L4 http://www.l4hq.org/