12. 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.
13. The Goal
Bite sized
Text-based communication
Independent
KISS
Naturally private methods
Naturally loosely coupled
Fail gracefully
Maximize processor
14.
15. Code Complexity
#1 indicator of bugs: code size ( > 9300 chars)
In the eye of the beholder: the Co-Worker Test
Dependency count - coupling
16. 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!
17. 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!
18. Application?
Applications are message passing systems with a bag of
objects in the middle with input and output at either
ends.
Object1
Object2
Object3
19. 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
21. Current: Method-based API
Maximizes coupling
Easy to add dependencies
Synchronous across objects (typically) – blocks
caller
Local
Understood
22. Method / Event Hybrid
Local reference to object
Synchronous emitter
Asynchronous listener
Same process / memory space
Same coupling
Same dependencies
23. Pure Event API
Local reference
Same dependency / Same coupling
Return values?
Semantics?
Not as understood
Something still wrong…
25. Pure Event with Hub
Asynchronous emitter
Asynchronous listener
NO local reference
Shared nothing
Loose coupling
Function callbacks
26. 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)
27. 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)
30. 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');
}
});
31. Typical Web Server/App
Browser
Controller /
Router
Sink/Source ALL
Session
communication
Servlet container Models
HTTP
540+ apache
modules
Server Authentication
DB connectors Authorization
Static content Threading
32. 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
33. EventHub Architecture
HTTP
Server
User
Session
Module
Event
Hub
Browser
DB
Module
Browser
View
34. 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
35. No Dropped Events
UNICAST
REGISTER
M M N
o EVENT FLOW o E
Event UNICAST
d Hub
REGISTER d W
u u
l DONE EVENT EVENT l
FLOW
e e
FINAL FLOW /
SHUTDOWN
Batch programming – job schedulerCoding pad– (72 columns) – because card (intro by IBM 1928) had 80 columns –but machines could only read 72 columns – a key puncher made a card –each card was 1 line of code - on tray to remote job entry = card reader = set in queue in memory = output to printer – look @ core dump if failed – repunch changes ~1980s crt came out & interactiveLate 1970s timesharing – DEC (ethernet & networking) & IBM (PS/0) came interactivityWhere we came fromWrite program on coding pad – give to keypunchers – feed into computer - wait (up to 24 hours) – get printout – repeat = batch processing – only operators ran computers – everything else offlineLong waits between steps – once computer running it can’t do anything else until program quits or dies80 columns card A 4.7 GB DVD, with 80 characters per card, would require about 58 million cards, or a stack about 10 km high.
OMG SLOW!!Pdp10Cpus still expensive so had to share them –bob’s big boy restaurant - time sharing you paid for what u used – did not have to own your own computer &/or can share it w/lots of people simultaneously (CLOUD!) – hooked up via terminal & modem – renting all of this stuff & tracking usage because a big business & security was now a concern – financial institutions didn’t want others to see their data (first sec. conf. 1971 because of it) until…CPUs became CHEAP! Cost of transistors plummeted. Don’t need timesharing anymore everyone has their own cpu (6502 $25!)But now had similar problem –instead of waiting for other people’s jobs to finish you were waiting for your own job to finish. bursty CPU activity followed by waiting for IO sitting at a terminal – waiting.Led to multiprogramming – running multiple processes at the same timeInitially coop mt = programs would voluntarily give up CPU – one bad program hung the system (pre Windows NT & 95 & Mac OS 9)Waiting for peripherals (tape) very slow so switched to another batch program – nothing was interactive so I didn’t matter how long each program tookBut people wanted to get on the computer! Time sharing – individuals ‘inefficient’ – groups not- time shared systems first polled & then interrupted for input when idleBursts of activity then idle = web apps! Single server can handle lots of simultaneous ‘users’Time sharing led to multiprogramming = cpus became cheap enough that time sharing wasn’t necessaryCooperative multitasking = tasks voluntarily giving up cpu – 1 program can hog cpu & bring server downPreemptive multitasking – cpus kicks u out – timeslice – OS can deal with external events like data coming inEvery process is IO bound or CPU bound – now with interrupts and preemptive MT processes no longer poll or busywait – when data is ready current process is context switched to the one that was waiting.IO bound process waits while CPU bound process executesAmiga first pMT then Windows NT and 95 & later macos 9.xBob bemerhttp://www.trailing-edge.com/~bobbemer/TIMESHAR.HTMU of Mich first timesharing machine – could not figure out how to bill time – so guy spent 10k hours on machine & built unix
Process context switches more costlyCrazy fastcpus1971 intel 4004 2300 transistors – address 640 bytes of memoryKeep cpus busyPreemptive multitaskingHighest priorityTimesliceProcessesScheduled by kernelNo shared memoryThreadsScheduled in userland or kernelShared memoryAll softwareCooporative multitasking
Cpu prices dropped – everyone can afford one1977 Apple II1977 TRS-801981 IBM PC1982 Commodore 641984 Apple MacEveryone has a cpu at home & at workSuddenly cpus have plenty of time lying aroundUntil mac there was nothing else to do – could not have multiple programms
So inter-process scheduling on a uniprocessor is handled!Uniprocessor systems can now reliably multitask between processes efficientlyMULTITASKING1984 macBut now everyone has their own CPU – unwashed masses need something to look at! Amiga Workbench 1.0 - 1985 – first preemptive multitasking…1985 windows 1.0 cooperative mtMultitasking coop in Windows before XP and Mac OSX before XLinux always preempt.Windows NT/95 first supported threads 1993Linux Kernel 2.6 kernel threads 1993 JAVA 1995! Green threads on Sun - The next issue was a responsive UI – all apps now have GUIs.Don’t wanna block Uis while work happening – threads share memory & are cheap to create but have issues. Windows OS optimized for threads – linux for processes-------------------------------------------------------------------But my app now has a UI – I need to be responsiveBut starting a process is ‘slow’ and IPC is cumbersome. It’d be neat Was waiting for disk – now I’m waiting for UI and network.What else can I do while I’m/CPU is waiting? Creating a new process WAS heavyweight and communicating between processes via IPC was cumbersome. My program can still do work while waiting for IO – how about ‘light weight processes’: threads
Computers had to WAIT – for user input – for disk drives & secondary storage & by the late 1980s/early 1990s networkInstead of people waiting – cpus were waiting
Process context switches more costlyCrazy fastcpus1971 intel 4004 2300 transistors – address 640 bytes of memoryKeep cpus busyPreemptive multitaskingHighest priorityTimesliceProcessesScheduled by kernelNo shared memoryThreadsScheduled in userland or kernelShared memoryAll softwareCooporative multitasking
Java 1996 (linux green threads) java 1.3 (2000) kernel threads (using clone) (windows threads in process itself)Pthreads 1995 – standardized api- Linux supportuserland threads – 2.6 kernel moved pthreads to kernel ghreadsUserland access to threading
Hardware support via hyper-threading came to Xenon 2002 and Pentium 4 2002 – needed OS SMP & HT support (Windows XP & Linux < 2.4)First dual core intel 2005 Pentium D desktopsAMD first dual core 2005 Athlon 64 X2Since 2005 we’ve been able to take full advantage of multicore/HT cpus with preemtivpemt + kernel threadsLinux kernel fully preemptible 2.6
unix philosophy:Doug McIlroy, the inventor of Unix pipesBrian Kernighan 1976Unix philosophy faqLoosely coupled set of independent modules working together w/o knowledge of the other focused on ONLY 1 thing
SmallJSON-izedUpgraded / restarted w/o effecting systemIPC vs. threadingPrivate methods hard to test – don’t use / need so many of them
Charles Perrow's "Catastrophic Potential" model: Normal Accidents: Living with High-Risk Technologies: systems-behavior expert Apps fails because systems complexity makes failures inevitable(At Chernobyl, tests of a new safety system helped produce the meltdown and subsequent fire.)Tightly coupled code = ‘bad’Loosely coupled code = ‘good’Complex = ‘bad’Simple = ‘good’What does that look like?
http://www.enerjy.com/papers.html - open source java projectsStatic code analysisComplexity measuresMoredeps = more tests
Required by your object to workExternal to objectPulled in by object: DI, or instantiation or passed in or globalTesting more difficult – mock/stub them all outSystem more brittle – complex & lots to maintainBesides the number of dependencies & length of dep chain: deps are described how they relate to your objectThe way dependencies are handled is described by….How are deps expressed??
Tight coupling – cannot be pulled apartLoose coupling – barely togetherCoupling describes dependeniesWhen testing need to deal with coupled deps
Tight coupling – cannot be pulled apartLoose coupling – barely togetherCoupling describes dependeniesWhen testing need to deal with coupled deps
You gotta have a referenceInstantiate or inject or globalYour object waits for your responseUNDERSTOOD so there’s that
With some eventsPromotes couplingFor JS:Load the fileInstantiate maybeUse
You gotta have a referenceInstantiate or inject or globalYour object waits for your response
e.g. ButtonConstructorClick eventStill need the object locally
Still same as method-based apisGet some asynchronicityBut basically very similar to method-basedProblems with using all events all the time – what about return values? Will each object have a mish-mash of interfaces? Still needs the object locally to fire/listen to its events.
This is a star architecture – with many emitters & listeners – anyone can be anythingAnalogous to a network switch- switch learns the topology – & unicast directly to listener if unicast event otherwise broadcastFrom network world.Given that apps pass messages from end to end – so do networks. There are control messages between nodes to help route messages.
http webserver brokers ALL communication for your webapp!http webserver brokers ALL LOGIC of you webappRestart whole thing for changesOh ya browser over there in the corner – a special case
Module can be in-browser or in-serverLocal or remote – anywhere on webBuild on IPC NOT threading
Views instantiate Models to use them1973 first proposed for smalltalk (inspiration for JS)Decouple model from viewsAsync-arch = split model – data independent of methodsTheory remains – communication changes – no more views instantiating models or controllers instantiating views
You don’t have to use threads anymore!The biggest gain of event-based arch – no more threads!
Don’t need to load scripts / libraries locally!
If it can happen it will happenApps failPieces dieBoxes crashShit happens
SmallJSON-izedUpgraded / restarted w/o effecting systemIPC vs. threadingPrivate methods hard to test – don’t use / need so many of them
JavaPerlJavascriptPythonRubyFlashErlang, Lua. GoWebSocktesHTTPIFRAMEJSONP PollingAJAX long pollingAJAX multipart streamingFlash
Microkernelmach
That’s all software! All threading was done by software – either in userland or in the kernel – CPUs are single threadedOnly supercomputers &/or specialized operating systems could handle multiple cpus UNICOS and IRIX – sys V variants – early 1990sNow they all run variants of linuxK computer in japan – 86000 ultrasparc64s – 10.51 petaflops – 864 racks