Presentation is loading. Please wait.

Presentation is loading. Please wait.

Serversideness Douglas Crockford Yahoo! Inc.. Server Side JavaScript 1996 Netscape LiveWire PHP-like. Fail. Now Node.js on V8. Event driven, turn based.

Similar presentations


Presentation on theme: "Serversideness Douglas Crockford Yahoo! Inc.. Server Side JavaScript 1996 Netscape LiveWire PHP-like. Fail. Now Node.js on V8. Event driven, turn based."— Presentation transcript:

1 Serversideness Douglas Crockford Yahoo! Inc.

2 Server Side JavaScript 1996 Netscape LiveWire PHP-like. Fail. Now Node.js on V8. Event driven, turn based execution. Win.

3 node.js node.js implements a web server in a JavaScript event loop. It is a high-performance event pump. fs.readFile( filename, encoding, function ( err, data ) {...}) Everything is (or can be) non-blocking. Except: –some synchronous functions –require

4 Your stuff runs on both sides JS/V8Browser DOM JS DOMnode.js YUI3 Your stuff YUI3

5 Turn A turn is started by an external event, such as the completion of an asynchronous request, a user action, or the ticking of the clock. A callback function associated with the event is called. It runs to completion. When it returns, the turn ends. No need for threads. No races. No deadlocks.

6 The Law of Turns Never wait. Never block. Finish fast.

7 Turns Nothing can ever block, not even I/O. Do not poll. Instead, register a callback. This is how browsers work. This is how servers should also work.

8 Long running tasks Two solutions for long running programs: Eteration: Break the task into multiple turns. Move the task into a separate process (workers).

9 Threads are evil In systems programming, threads are a necessary evil. In application programming, threads are just evil. Threads provide a deceptively simple model of concurrency. Threads are subject to races and deadlocks.

10 Two threads my_array = []; 1.my_array[my_array.length] = 'a'; 2.my_array[my_array.length] = 'b'; ['a', 'b'] ['b', 'a']

11 Two threads my_array = []; 1.my_array[my_array.length] = 'a'; 2.my_array[my_array.length] = 'b'; ['a', 'b'] ['b', 'a'] ['a'] ['b']

12 my_array[my_array.length] = 'a'; length_a = my_array.length; my_array[length_a] = 'a'; if (length_a >= my_array.length) { my_array.length = length_a + 1; }

13 my_array[my_array.length] = 'a'; my_array[my_array.length] = 'b'; length_a = my_array.length; length_b = my_array.length; my_array[length_a] = 'a'; if (length_a >= my_array.length) { my_array[length_b] = 'b'; my_array.length = length_a + 1; } if (length_b >= my_array.length) { my_array.length = length_b + 1; }

14 It is impossible to have application integrity when subject to race conditions. Read - Modify - Write

15 Mutual Exclusion semaphore monitor rendezvous synchronization This used to be operating system stuff. It has leaked into applications because of networking and the multi-core problem.

16 Deadlock

17

18 Remote Procedure Call Combines two great ideas, functions and networking, producing a really bad idea. Attempts to isolate programs from time. The program blacks out. In reading the program, it is by design difficult to see where time is lost. This can result in a terrible experience for the user. Lost time === annoying delays. Keeping the user waiting without warning is disrespectful and rude.

19 Turn-based program avoids the problems but is unfamiliar to non-JavaScript programmers.

20 Quiz 1 function funky(o) { o = null; } var x = []; funky(x); alert(x); A.null B.[] C.undefined D.throw

21 Quiz 2 function swap(a, b) { var temp = a; a = b; b = temp } var x = 1, y = 2; swap(x, y); alert(x); A.1 B.2 C.undefined D.throw

22 Quiz 3 Make a function that puts a value in a variable when it is finished.

23 Pass the name of the variable. function do_it(inputs, name) {... eval(name + ' = ' + result); window[name] = result; } Not only bad practice, but illegal in ES5/strict.

24 function do_it(inputs, obj, name) {... obj[name] = result; } Gives do-it too much authority.

25 function do_it(inputs, func) {... func(result); } We pass a function to do_it. do_it cannot abuse the function. The function cannot abuse do_it. func is a callback.

26 Callbacks Temporal isolation. Event handlers. Timers. Lightweight, powerful, expressive. Continuation.

27 function do_it(inputs, callback) {... callback(result); } do_it(my_inputs, function (result) { my_object.blah = result; });

28 Generalize. function storer(obj, name) { return function (result) { obj[name] = result; }; } do_it(inputs, storer(my_object, 'blah'));

29 function storer_maker(obj) { return function(name) { return function (result) { obj[name] = result; }; } my_storer = storer_maker(my_object); do_it(my_inputs, my_storer('blah'));

30 function once(func) { return function () { var f = func; func = null; return f.apply(this, arguments); }; } do_it(my_inputs, once(storer(my_object, 'blah')));

31 function sequence() { var slice = Array.prototype.slice, functions = slice.call(arguments, 0); return function () { var args = slice.call(arguments, 0); functions.forEach(function (func) { func.apply(null, args); }); }; }

32 function revokerness(func) { return { revocable: function () { return func.apply(this, arguments); }, revoker: function () { func = null; } }; }

33 do_it(my_inputs, once(sequence( storer(my_object, 'blah'), storer(other_object, 'wow'), alert )));

34 Server programming can be more complicated. Call 20 services, each contributing material for the page, wait until all respond, then assemble the result. Call a service, use its result to call another service, avoiding deeply nested event handlers.

35 Requestor function requestor(sync) { service_request(param, function (error, result) { sync(error, result); }); }

36 Requestor maker function request_maker(param) { return function (sync) { service_request(param, function (error, result) { sync(error, result); }); }; }

37 Requestor maker maker function request_maker_maker(service) { return function (param) { return function (sync) { service(param, function (error, result) { sync(error, result); }); }; }

38 Requestor maker maker request_maker_maker (service) (param) (sync);

39 Composition par([requestor…], sync, timeout); seq([requestor…], sync, timeout); map([requestor…], sync, timeout);

40 Composition function makers paror([requestor…], timeout) seqor([requestor…], timeout) mapor([requestor…], timeout)

41 Also see Directing JavaScript with Arrows www.cs.umd.edu/~mwh/papers/jsarrows.pdf Reactive Extensions for JavaScript http://blogs.msdn.com/b/rxteam/archive/ 2010/03/17/reactive-extensions-for- javascript.aspx (fab) https://github.com/jed/fab

42 Thank you and good night.


Download ppt "Serversideness Douglas Crockford Yahoo! Inc.. Server Side JavaScript 1996 Netscape LiveWire PHP-like. Fail. Now Node.js on V8. Event driven, turn based."

Similar presentations


Ads by Google