JS everywhere 2011

3,872 views

Published on

Published in: Technology
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,872
On SlideShare
0
From Embeds
0
Number of Embeds
200
Actions
Shares
0
Downloads
37
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

JS everywhere 2011

  1. 1. The Future of Server Side JavaScript
  2. 2. /me <ul><li>#startups </li></ul><ul><li>#akshell </li></ul><ul><li>#ringojs </li></ul><ul><li>#moscowjs </li></ul><ul><li>#dailyjs </li></ul>
  3. 4. Node.js <ul><li>Ideal use cases </li></ul><ul><ul><li>Real time apps, infrastructure duct tape </li></ul></ul><ul><li>Badly suited for </li></ul><ul><ul><li>CRUD, command line tools, CPU heavy loads </li></ul></ul><ul><li>Easy to get started with </li></ul><ul><ul><li>Difficult to get into production </li></ul></ul>
  4. 7. Akshell NarwhalJS RingoJS Wakanda GPSEE v8cgi
  5. 8. ServerJS Fragmentation
  6. 9. <ul><li>Sync vs. Async </li></ul>
  7. 11. <ul><li>“ async style is kicking sync style's back end” </li></ul>
  8. 13. <ul><li>sync is “on top of” async – a higher level of abstraction </li></ul>
  9. 14. Sync vs. Async function add(callback) { http.get(url1, function(response1) { var part1 = response1.data; http.get(url2, function(response2) { var part2 = response2.data; callback(part1 + part2); } } }
  10. 15. Sync vs. Async http.get(url1).data + http.get(url2).data
  11. 16. Interoperability <ul><li>Pure JavaScript modules run anywhere </li></ul><ul><ul><li>Templating, parsing, formatting, encoding </li></ul></ul><ul><li>Anything doing I/O exposes sync or async API </li></ul><ul><ul><li>Defines the interface exposed by higher level packages </li></ul></ul>
  12. 19. CommonJS /1 <ul><li>Modules/1.1 </li></ul><ul><li>Packages/1.0 </li></ul><ul><li>Assert </li></ul><ul><li>Console </li></ul><ul><li>System/1.0 </li></ul>
  13. 20. CommonJS /2 <ul><li>Binary/B </li></ul><ul><li>IO/A </li></ul><ul><li>JSGI 0.3 </li></ul><ul><li>Filesystem/A </li></ul>
  14. 21. CommonJS /3 <ul><li>HTTP Client /A </li></ul><ul><li>Sockets/A </li></ul><ul><li>Subprocess </li></ul>
  15. 22. common-node <ul><li>Implements synchronous CommonJS proposals using node-fibers </li></ul><ul><li>Traceur to support latest language features </li></ul><ul><li>Bridges the gap between platforms, sync and async </li></ul>
  16. 23. <ul><li>What it's good for? </li></ul>
  17. 24. everything!
  18. 25. What's it actually good for? <ul><li>Business logic </li></ul><ul><ul><li>Lots of state, fine grained error handling </li></ul></ul><ul><li>CRUD </li></ul><ul><ul><li>Java, Rails, PHP, Python </li></ul></ul><ul><li>Command line tools </li></ul><ul><li>Cross platform portability </li></ul>
  19. 26. On Threads & Fibers <ul><li>“ Threads suck” </li></ul><ul><ul><li>- Brendan Eich, creator of JavaScript </li></ul></ul><ul><li>“ Fibers introduce interleaving hazards — Any function call can cause a yield and then your closure invariants *may be* broken.” </li></ul><ul><ul><li>- Kris Kowal, creator of CommonJS/Modules </li></ul></ul>
  20. 27. Concurrency in JavaScript <ul><li>“ You shouldn’t think that event-based concurrency eliminates synchronization, or shared memory, or anything other than preemption” - Sam Tobin-Hochstadt, member of the Ecma TC39 committee on JavaScript </li></ul>
  21. 28. fibers /1 <ul><li>Co routine implementation using libcoro </li></ul><ul><li>Co-operative multitasking </li></ul><ul><li>Implicit synchronization </li></ul>
  22. 29. fibers /2 <ul><li>Not a fork or a hack of Node </li></ul><ul><li>No wrapper script required </li></ul><ul><li>V8 Context and 64KB stack per fiber </li></ul><ul><li>Will run on Windows </li></ul>
  23. 30. Node.js process [ closure closure t ->
  24. 31. RingoJS (0.8) process thread stack process thread stack t ->
  25. 32. Common Node (fibers) process fiber stack fiber stack [ t ->
  26. 33. Node.js Common Node RingoJS Process Count Single Single Multiple State Closure Fiber Stack Thread Stack Multitasking User (co-op) Library (co-op) OS (pre-empt) Memory Usage Low Low High “ Jitter” High High Low
  27. 34. Internals - sleep <ul><li>exports.sleep = function(milliseconds) { </li></ul><ul><li>var fiber = Fiber.current; </li></ul><ul><li>setTimeout(function() { </li></ul><ul><li>fiber.run(); </li></ul><ul><li>}, milliseconds); </li></ul><ul><li>yield(); </li></ul><ul><li>} ; </li></ul>
  28. 35. Internals – HttpClient /1 <ul><li>var req = http.request(options, function(r) { </li></ul><ul><li>fiber.run(r); </li></ul><ul><li>}); </li></ul><ul><li>req.on('error', function(error) { </li></ul><ul><li>fiber.run(error); </li></ul><ul><li>}); </li></ul><ul><li>this.guts.body.forEach(function(block) { </li></ul><ul><li>req.write(block.buffer || block); </li></ul><ul><li>}); </li></ul><ul><li>req.end(); </li></ul>
  29. 36. Internals – HttpClient /2 <ul><li>var result = yield(); </li></ul><ul><li>if(result instanceof Error) </li></ul><ul><li>throw new Error(result.message); </li></ul><ul><li>return { </li></ul><ul><li>status: result.statusCode, </li></ul><ul><li>headers: result.headers, </li></ul><ul><li>body: new Stream(result) </li></ul><ul><li>}; </li></ul>
  30. 37. Internals - IO <ul><li>// on 'data', 'end', 'error' </li></ul><ul><li>// pause when draining </li></ul><ul><li>var listeners = attach(this.stream); </li></ul><ul><li>var data = yield(); </li></ul><ul><li>detach(this.stream, listeners); </li></ul>
  31. 38. <ul><li>Examples </li></ul>
  32. 39. JSGI <ul><li>exports.app = function(request) { </li></ul><ul><li>return { </li></ul><ul><li>status: 200, </li></ul><ul><li>headers: {}, </li></ul><ul><li>body: ['Hello World!'] </li></ul><ul><li>// openRaw(module.filename) </li></ul><ul><li>}; </li></ul><ul><li>}; </li></ul>
  33. 40. Spawn & Sleep <ul><li>exports.app = function(request) { </li></ul><ul><li>spawn(function() { </li></ul><ul><li>sleep(10000); </li></ul><ul><li>console.log('Hello Server!'); </li></ul><ul><li>}); </li></ul><ul><li>return { </li></ul><ul><li>status: 200, </li></ul><ul><li>headers: {}, </li></ul><ul><li>body: ['Hello Client!'] </li></ul><ul><li>}; </li></ul><ul><li>}; </li></ul>
  34. 41. HTTP Proxy <ul><li>var HttpClient = require('httpclient').HttpClient; </li></ul><ul><li>exports.app = function(req) { </li></ul><ul><li>req.url = 'http://nodejs.org'; </li></ul><ul><li>return new HttpClient(req).finish(); </li></ul><ul><li>}; </li></ul>
  35. 42. Twitter Streaming /1 <ul><li>var stream = new TextStream( new HttpClient({ </li></ul><ul><li>method: 'POST', </li></ul><ul><li>url: '...', </li></ul><ul><li>headers: {} </li></ul><ul><li>body: ['track='+system.args[4]], </li></ul><ul><li>timeout: 10000 </li></ul><ul><li>}).finish().body); </li></ul>
  36. 43. Twitter Streaming /2 <ul><li>var line; </li></ul><ul><li>while(true) { </li></ul><ul><li>line = stream.readLine(); </li></ul><ul><li>if(!line.length) break; </li></ul><ul><li>if(line.length > 1) { </li></ul><ul><li>var message = JSON.parse(line); </li></ul><ul><li>console.log(message.text); </li></ul><ul><li>} </li></ul><ul><li>} </li></ul>
  37. 44. Benchmarks ab -n 50000 -c 50
  38. 45. hello-world <ul><li>exports.app = function() { </li></ul><ul><ul><li>return { </li></ul></ul><ul><ul><ul><li>status: 200, </li></ul></ul></ul><ul><ul><ul><li>headers: { </li></ul></ul></ul><ul><ul><ul><ul><li>'Content-Type': 'text/plain' </li></ul></ul></ul></ul><ul><ul><ul><li>}, </li></ul></ul></ul><ul><ul><ul><li>body: ['Hello World!n'] </li></ul></ul></ul><ul><ul><li>}; </li></ul></ul><ul><li>}; </li></ul>
  39. 47. string-alloc <ul><li>exports.app = function(request) { </li></ul><ul><ul><li>for( var i = 1; i <= 50; i++) </li></ul></ul><ul><ul><ul><li>b.decodeToString(&quot;ascii&quot;); </li></ul></ul></ul><ul><ul><li>return { </li></ul></ul><ul><ul><ul><li>status: 200, </li></ul></ul></ul><ul><ul><ul><li>headers: {}, </li></ul></ul></ul><ul><ul><ul><li>body: [b] </li></ul></ul></ul><ul><ul><li>}; </li></ul></ul><ul><li>}; </li></ul>
  40. 49. parse-json <ul><li>exports.app = function(request) { </li></ul><ul><ul><li>JSON.parse(json); </li></ul></ul><ul><ul><li>return { </li></ul></ul><ul><ul><ul><li>status: 200, </li></ul></ul></ul><ul><ul><ul><li>headers: {}, </li></ul></ul></ul><ul><ul><ul><li>body: [json] </li></ul></ul></ul><ul><ul><li>}; </li></ul></ul><ul><li>}; </li></ul>
  41. 51. static-file <ul><li>exports.app = function() { </li></ul><ul><li>return { </li></ul><ul><li>status: 200, </li></ul><ul><li>headers: {}, </li></ul><ul><li>body: openRaw('../README.md') </li></ul><ul><li>}; </li></ul><ul><li>}; </li></ul>
  42. 53. set-timeout <ul><li>exports.app = function() { </li></ul><ul><li>sleep(100); </li></ul><ul><li>return { </li></ul><ul><li>status: 200, </li></ul><ul><li>headers: {}, </li></ul><ul><li>body: [] </li></ul><ul><li>}; </li></ul><ul><li>}; </li></ul>
  43. 55. Throughput
  44. 56. Contributing <ul><li>Google “ common node ” </li></ul><ul><li>github.com/olegp/common-node/ </li></ul><ul><li>npm -g install common-node </li></ul>
  45. 57. SyncJS Fragmentation
  46. 58. Toolkits vs. Frameworks
  47. 64. Next Steps <ul><li>Stick backport </li></ul><ul><li>Database access </li></ul><ul><ul><li>selectjs.com </li></ul></ul><ul><li>Higher level packages (wiki) </li></ul>
  48. 65. common-utils <ul><li>base64: encode, decode </li></ul><ul><li>hash: sha1 etc. </li></ul><ul><li>url: parse, format, resolve </li></ul><ul><li>string: format, trim etc. </li></ul><ul><li>date: format, add, before, after etc. </li></ul><ul><li>array: contains etc. </li></ul><ul><li>object: clone, merge etc. </li></ul>
  49. 66. One more thing ... <ul><li>Third party services & APIs </li></ul><ul><ul><li>olegp/rest-wrapper </li></ul></ul><ul><ul><li>thelockerproject.org </li></ul></ul><ul><li>Browser based IDEs (Cloud9, Akshell) </li></ul><ul><li>Social hosting </li></ul><ul><ul><li>PINF, automatic redeployment, continuous integration etc. </li></ul></ul>
  50. 67. Summary <ul><li>sync and async will co-exist </li></ul><ul><li>toolkits instead of frameworks </li></ul><ul><li>implementation driven de-facto standards </li></ul><ul><li>we are just getting started! </li></ul>
  51. 68. <ul><li>Thank you! </li></ul><ul><li>@olegpodsechin </li></ul>

×