Professional Documents
Culture Documents
Erlang, Clojure & Co.: Was der Mainstream von Alternativen lernen kann
http://www.innoq.com
Node.js
Node.js
Node.js
Node.js
Node.js
Prolog
Anforderungen...
Hinweise:
1. Es gibt fnf Huser mit je einer anderen Farbe. 2. In jedem Haus wohnt eine Person anderer Nationalitt. 3. Jeder Hausbewohner bevorzugt ein bestimmtes Getrnk, raucht eine bestimmte Zigarettenmarke und hlt ein bestimmtes Haustier. 4. Keine der fnf Personen trinkt das gleiche Getrnk, raucht die gleichen Zigaretten oder hlt das gleiche Tier wie seine Nachbarn. Frage: Wem gehrt der Fisch?
Der Brite lebt im roten Haus. Der Schwede hlt einen Hund. Der Dne trinkt gern Tee. Das grne Haus steht direkt links neben dem weien Haus. Der Besitzer des grnen Hauses trinkt Kaffee. Die Person, die Pall Mall raucht, hlt einen Vogel. Der Mann, der im mittleren Haus wohnt, trinkt Milch. Der Besitzer des gelben Hauses raucht Dunhill. Der Norweger wohnt im ersten Haus. Der Marlboro-Raucher wohnt neben dem, der eine Katze hlt. Der Mann, der ein Pferd hlt, wohnt neben dem, der Dunhill raucht. Der Winfield-Raucher trinkt gern Bier. Der Norweger wohnt neben dem blauen Haus. Der Deutsche raucht Rothmans. Der Marlboro-Raucher hat einen Nachbarn, der Wasser trinkt.
Lsung in Prolog
run :X =[_,_,_,_,_],/* Es gibt (nebeneinander) 5 Huser */ member([rot,brite,_,_,_],X),/* Der Brite lebt im roten Haus */ member([_,schwede,_,_,hund],X),/* Der Schwede hlt einen Hund */ member([_,daene,tee,_,_],X),/* Der Dne trinkt gern Tee */ links([gruen,_,_,_,_],[weiss,_,_,_,_],X),/* Das grne Haus steht links vom weien Haus */ member([gruen,_,kaffee,_,_],X),/* Der Besitzer des grnen Hauses trinkt Kaffee */ member([_,_,_,pallmall,vogel],X),/* Die Person, die Pall Mall raucht, hlt einen Vogel */ mittleres([_,_,milch,_,_],X),/* Der Mann, der im mittleren Haus wohnt, trinkt Milch */ member([gelb,_,_,dunhill,_],X),/* Der Besitzer des gelben Hauses raucht Dunhill */ erstes([_,norweger,_,_,_],X),/* Der Norweger wohnt im 1. Haus */ neben([_,_,_,marlboro,_],[_,_,_,_,katze],X),/* Der Marlboro-Raucher wohnt neben Katzenbesitzer */ neben([_,_,_,_,pferd],[_,_,_,dunhill,_],X),/* Der Pferdehalter wohnt neben dem Dunhillraucher */ member([_,_,bier,winfield,_],X),/* Der Winfield-Raucher trinkt gern Bier */ neben([_,norweger,_,_,_],[blau,_,_,_,_],X),/* Der Norweger wohnt neben dem blauen Haus */ member([_,deutsche,_,rothmans,_],X),/* Der Deutsche raucht Rothmans */ neben([_,_,_,marlboro,_],[_,_,wasser,_,_],X),/* Der Nachbar des Marlboro-Rauchers trinkt Wasser */ member([_,N,_,_,fisch],X),/* Der mit der Nationalitt N hat einen Fisch */ write(X),nl,/* Ausgabe aller Huser */ write('Der '),write(N),write(' hat einen Fisch als Haustier.'),nl.
Lsung in Prolog
run :X =[_,_,_,_,_],/* Es gibt (nebeneinander) 5 Huser */ member([rot,brite,_,_,_],X), /* Der Brite lebt im roten Haus */ member([_,schwede,_,_,hund],X), /* Der Schwede hlt einen Hund */ member([_,daene,tee,_,_],X), /* Der Dne trinkt gern Tee */ links([gruen,_,_,_,_],[weiss,_,_,_,_],X), /* Das grne Haus steht links vom weien Haus */
%.....
Lsung in Prolog
Prolog
Basis: Unifikation von Termen
(Mustererkennung)
Vorgabe von Fakten und Regeln (mit freien Variablen) Prolog versucht, Wahrheit zu beweisen Beispiel: neben(A, b, [a,c,b,d]) -> A=c A=d
Prolog...
Prolog: Kernkonzepte
Regelorientierung Backtracking Deklarativer Ansatz
Prolog: Praxistauglichkeit
Schwierig (riskant): Integration in JavaMainstream tu-Prolog als Eclipse-Plugin, experimentell + fragil Gut geeignet fr Planungsprobleme
Prolog: Java-Bibliotheken
Regelsysteme heute geschfts- und integrationsfhig: kommerzielle Regel-Engines freie Regel-Engine(s), etwa JBoss-Drools
JBoss Drools
http://upload.wikimedia.org/wikipedia/en/1/1
Clojure
Clojure: Datenstrukturen
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Clojure: Datenstrukturen
Numbers Strings Characters Keywords Symbols Regexps Lists Vectors Maps Sets
2 3 4 0.234 3/5 -2398989892820093093090292321 "Hello" "World" \a \b \c :first :last a b c #"Ch.*se" (a b c) ((:first :last "Str" 3) (a b)) [2 4 6 9 23] [2 4 6 [8 9] [10 11] 9 23] {:de "Deutschland", :fr "France"} #{"Bread" "Cheese" "Wine"}
Syntax
(ns sample.grep !!"A simple complete Clojure program." !!(:use [clojure.contrib.io :only [read-lines]]) !!(:gen-class)) (defn numbered-lines [lines] !!(map vector (iterate inc 0) lines))
Clojure: Beispie;l
(defn grep-in-file [pattern file] !!{file (filter #(re-find pattern (second %)) (numbered-lines (read-lines file)))}) (defn grep-in-files [pattern files] !!(apply merge (map #(grep-in-file pattern %) files))) (defn print-matches [matches] !!(doseq [[fname submatches] matches, [line-no, match] submatches] !!!!(println (str fname ":" line-no ":" match)))) !!!!!!!!!!!! (defn -main [pattern & files] !!(if (or (nil? pattern) (empty? files)) !!!!(println "Usage: grep <pattern> <file...>") !!!!(do !!!!!!(println (format "grep started with pattern %s and file(s) %s" pattern (apply str (interpose ", " files)))) !!!!!!(print-matches (grep-in-files (re-pattern pattern) files)) !!!!!!(println "Done."))))
(ns sample.grep !!"A simple complete Clojure program." !!(:use [clojure.contrib.io :only [read-lines]]) !!(:gen-class)) (defn numbered-lines [lines] !!(map vector (iterate inc 0) lines))
Clojure: Beispie;l
(defn grep-in-file [pattern file] !!{file (filter #(re-find pattern (second %)) (numbered-lines (read-lines file)))}) (defn grep-in-files [pattern files] !!(apply merge (map #(grep-in-file pattern %) files))) (defn print-matches [matches] !!(doseq [[fname submatches] matches, [line-no, match] submatches] !!!!(println (str fname ":" line-no ":" match)))) !!!!!!!!!!!! (defn -main [pattern & files] !!(if (or (nil? pattern) (empty? files)) !!!!(println "Usage: grep <pattern> <file...>") !!!!(do !!!!!!(println (format "grep started with pattern %s and file(s) %s" pattern (apply str (interpose ", " files)))) !!!!!!(print-matches (grep-in-files (re-pattern pattern) files)) !!!!!!(println "Done."))))
(ns sample.grep !!"A simple complete Clojure program." !!(:use [clojure.contrib.io :only [read-lines]]) !!(:gen-class)) (defn numbered-lines [lines] !!(map vector (iterate inc 0) lines))
Clojure: Beispie;l
(defn grep-in-file [pattern file] !!{file (filter #(re-find pattern (second %)) (numbered-lines (read-lines file)))}) (defn grep-in-files [pattern files] !!(apply merge (map #(grep-in-file pattern %) files))) (defn print-matches [matches] !!(doseq [[fname submatches] matches, [line-no, match] submatches] !!!!(println (str fname ":" line-no ":" match)))) !!!!!!!!!!!! (defn -main [pattern & files] !!(if (or (nil? pattern) (empty? files)) !!!!(println "Usage: grep <pattern> <file...>") !!!!(do !!!!!!(println (format "grep started with pattern %s and file(s) %s" pattern (apply str (interpose ", " files)))) !!!!!!(print-matches (grep-in-files (re-pattern pattern) files)) !!!!!!(println "Done."))))
(ns sample.grep !!"A simple complete Clojure program." !!(:use [clojure.contrib.io :only [read-lines]]) !!(:gen-class)) (defn numbered-lines [lines] !!(map vector (iterate inc 0) lines))
Clojure: Beispie;l
(defn grep-in-file [pattern file] !!{file (filter #(re-find pattern (second %)) (numbered-lines (read-lines file)))}) (defn grep-in-files [pattern files] !!(apply merge (map #(grep-in-file pattern %) files))) (defn print-matches [matches] !!(doseq [[fname submatches] matches, [line-no, match] submatches] !!!!(println (str fname ":" line-no ":" match)))) !!!!!!!!!!!! (defn -main [pattern & files] !!(if (or (nil? pattern) (empty? files)) !!!!(println "Usage: grep <pattern> <file...>") !!!!(do !!!!!!(println (format "grep started with pattern %s and file(s) %s" pattern (apply str (interpose ", " files)))) !!!!!!(print-matches (grep-in-files (re-pattern pattern) files)) !!!!!!(println "Done."))))
(ns sample.grep !!"A simple complete Clojure program." !!(:use [clojure.contrib.io :only [read-lines]]) !!(:gen-class)) (defn numbered-lines [lines] !!(map vector (iterate inc 0) lines))
Clojure: Beispie;l
(defn grep-in-file [pattern file] !!{file (filter #(re-find pattern (second %)) (numbered-lines (read-lines file)))}) (defn grep-in-files [pattern files] !!(apply merge (map #(grep-in-file pattern %) files))) (defn print-matches [matches] !!(doseq [[fname submatches] matches, [line-no, match] submatches] !!!!(println (str fname ":" line-no ":" match)))) !!!!!!!!!!!! (defn -main [pattern & files] !!(if (or (nil? pattern) (empty? files)) !!!!(println "Usage: grep <pattern> <file...>") !!!!(do !!!!!!(println (format "grep started with pattern %s and file(s) %s" pattern (apply str (interpose ", " files)))) !!!!!!(print-matches (grep-in-files (re-pattern pattern) files)) !!!!!!(println "Done."))))
(ns sample.grep !!"A simple complete Clojure program." !!(:use [clojure.contrib.io :only [read-lines]]) !!(:gen-class)) (defn numbered-lines [lines] !!(map vector (iterate inc 0) lines))
Clojure: Beispie;l
(defn grep-in-file [pattern file] !!{file (filter #(re-find pattern (second %)) (numbered-lines (read-lines file)))}) (defn grep-in-files [pattern files] !!(apply merge (map #(grep-in-file pattern %) files))) (defn print-matches [matches] !!(doseq [[fname submatches] matches, [line-no, match] submatches] !!!!(println (str fname ":" line-no ":" match)))) !!!!!!!!!!!! (defn -main [pattern & files] !!(if (or (nil? pattern) (empty? files)) !!!!(println "Usage: grep <pattern> <file...>") !!!!(do !!!!!!(println (format "grep started with pattern %s and file(s) %s" pattern (apply str (interpose ", " files)))) !!!!!!(print-matches (grep-in-files (re-pattern pattern) files)) !!!!!!(println "Done."))))
Clojure: Features
Persistent data structures Support for concurrent programming Sequences Destructuring List comprehensions Metadata Optiional type information Multimethods Pre & Post Conditions Records/Protocols Extensive core and contrib libraries
Thursday, April 19, 12
Clojure: Features
Persistent data structures Support for concurrent programming Sequences Destructuring List comprehensions Metadata Optiional type information Multimethods Pre & Post Conditions Records/Protocols Extensive core and contrib libraries
Thursday, April 19, 12
4711: Person rst: John last: Smith 0815: Person rst: Jane last: Doe
4711: Person rst: John last: Smith 0815: Person rst: Jane last: Doe
4711: Person rst: John last: Smith 0815: Person rst: Jane last: Doe
4711: Person rst: John last: Smith 0815: Person rst: Jane last: Doe
4711: Person rst: John last: Smith 0815: Person rst: Jane last: Doe
4711: Person rst: John last: Smith 0815: Person rst: Jane last: Doe
4711: Person rst: John last: Smith 0815: Person rst: Jane last: Doe
The Problem!
Immutability
Immutability
user> (def v (vec (range 10)))
Immutability
user> (def v (vec (range 10))) #'user/v
Immutability
user> (def v (vec (range 10))) #'user/v user> v
Immutability
user> (def v (vec (range 10))) #'user/v user> v [0 1 2 3 4 5 6 7 8 9]
Immutability
user> (def v (vec (range 10))) #'user/v user> v [0 1 2 3 4 5 6 7 8 9] user> (assoc v 1 99)
Immutability
user> (def v (vec (range 10))) #'user/v user> v [0 1 2 3 4 5 6 7 8 9] user> (assoc v 1 99) [0 99 2 3 4 5 6 7 8 9]
Immutability
user> (def v (vec (range 10))) #'user/v user> v [0 1 2 3 4 5 6 7 8 9] user> (assoc v 1 99) [0 99 2 3 4 5 6 7 8 9] user> v
Immutability
user> (def v (vec (range 10))) #'user/v user> v [0 1 2 3 4 5 6 7 8 9] user> (assoc v 1 99) [0 99 2 3 4 5 6 7 8 9] user> v [0 1 2 3 4 5 6 7 8 9]
Immutability
user> (def v (vec (range 10))) #'user/v user> v [0 1 2 3 4 5 6 7 8 9] user> (assoc v 1 99) [0 99 2 3 4 5 6 7 8 9] user> v [0 1 2 3 4 5 6 7 8 9] user> (def v2 (assoc v 1 99))
Immutability
user> (def v (vec (range 10))) #'user/v user> v [0 1 2 3 4 5 6 7 8 9] user> (assoc v 1 99) [0 99 2 3 4 5 6 7 8 9] user> v [0 1 2 3 4 5 6 7 8 9] user> (def v2 (assoc v 1 99)) #'user/v2
Immutability
user> (def v (vec (range 10))) #'user/v user> v [0 1 2 3 4 5 6 7 8 9] user> (assoc v 1 99) [0 99 2 3 4 5 6 7 8 9] user> v [0 1 2 3 4 5 6 7 8 9] user> (def v2 (assoc v 1 99)) #'user/v2 user> v2
Immutability
user> (def v (vec (range 10))) #'user/v user> v [0 1 2 3 4 5 6 7 8 9] user> (assoc v 1 99) [0 99 2 3 4 5 6 7 8 9] user> v [0 1 2 3 4 5 6 7 8 9] user> (def v2 (assoc v 1 99)) #'user/v2 user> v2 [0 99 2 3 4 5 6 7 8 9]
99
99
99
v2
99
Performance Guarantees
hash-map sorted-map hash-set sorted-set vector queue list lazy seq
constant constant constant (tail) (head) (head) linear constant (head) constant (head) constant linear constant (head) constant (head) constant linear constant (head) constant (head) linear
nearconstant nearlogarith nearlogarith nearconstant mic constant mic constant constant (tail) constant (tail) constant constant constant constant constant
(defn withdraw [account amount] !!(assoc account :balance (- (account :balance) amount)))
(defn withdraw [account amount] !!(assoc account :balance (- (account :balance) amount)))
(defn deposit [account amount] !!(assoc account :balance (+ (account :balance) amount)))
acc1: {:balance 1300, :owner "alice"} acc2: {:balance 1100, :owner "bob"} acc3: {:balance 600, :owner "charles"}
Clojure: Kernkonzepte
Funktionale Programmierung Homoikonizitt Software Transactional Memory
Clojure: Praxistauglichkeit
Technisch: Einsatzfhig und praxistauglich Politisch: Schwer durchsetzbar (?) Chance und Risiko Nische: Concurrent and Correct
Clojure: Java-Bibliotheken
Functional Java (http://functionaljava.org/) Google Guava java.util.concurrent JDK 8 (ParallelArray & Co.) bzw. JSR 166y
Clojure: Java-Idiome
Immutability Anonymous Inner Classes Daten statt spezifische Klassen
Erlang
Erlang Beispiel
Erlang - Theorie
Erlang - Theorie
Verteilung auf Knoten (Erlang-Nodes) Viele Knoten pro physischer Hardware (SEHR) viele ErlangProzesse pro Knoten
Thursday, April 19, 12
call functions
Erlang - Womit?
Emacs + make + Shell % for hardcore-geeks
Erlang - Theorie
123, 17.4, abcd, start_with_lowercase, quoted with blanks
Erlang - Theorie
A = 10 ! Erfolg - bindet A an 10
PatternMatching
{B, C, D} = {10, foo, bar} Erfolg - bindet B an 10, C an foo und D an bar {A, A, B} = {abc, abc, foo} ! Erfolg - bindet A an abc, B an foo ! {A, A, B} = {abc, def, 123} ! Fail
Erlang - Theorie
Funktionen
-module(mathStuff). ! -export([factorial/1, area/1]). ! factorial(0) -> 1; factorial(N) -> N * factorial(N-1). ! area({square, Side}) -> ! ! Side * Side; area({circle, Radius}) -> ! ! % almost :-) ! ! 3 * Radius * Radius; area(Other) -> ! ! {invalid_object, Other}.
Prozesse
Erlang - Theorie
PID A
PID = spawn( foo ). B! {self(), foo}.
foo
PID B
receive {A, foo"} -> fn_foo; end.
Erlang: Kernkonzepte
Funktionale Programmierung Aktormodell Leichtgewichtige Prozesse Hot Swapping
Erlang: Praxistauglichkeit
Erprobt Server mit vielen parallelen Zugriffen (Protokollserver, Datenbanken, ) Systeme mit hchsten VerfgbarkeitsAnforderungen
Erlang: Beispiele
CouchDB Facebook-Chat RIAK Scalaris
(transaktionale, hoch skalierbare in-memory DB)
ejabberd Disco
(MapReduce von Nokia)
Amazon SimpleDB
Erlang: Java-Bibliotheken
Akka (http://akka.io/) Kilim (http://www.malhar.net/sriram/ kilim/)
Erlang: Java-Idiome
Immutability, Anonymous Inner Classes Active Objects Message Queues
Node.js
Node.js-Architektur
API (JavaScript)
v8
libev
libeio
http_parser
c_ares
var net = require('net'); var server = net.createServer(function (socket) { socket.write("Echo server\r\n"); socket.pipe(socket); }) server.listen(8124, "127.0.0.1");
Beispiele: http://github.com/stilkov/node-samples
echo.js
Thursday, April 19, 12
var net = require('net'); var server = net.createServer(function (socket) { socket.write("Echo server\r\n"); socket.setEncoding('ascii'); socket.on('data', function(data) { socket.write(data.toUpperCase()); }); }); server.listen(8124, "127.0.0.1");
echo-upcase.js
Thursday, April 19, 12
var sys = require("sys"), http = require("http"), url = require("url"), path = require("path"), fs = require("fs"); var dir = process.argv[2] || './public'; var port = parseFloat(process.argv[3]) || 8080; sys.log('Serving files from ' + dir + ', port is ' + port); http.createServer(function(request, response) { var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), dir, uri); path.exists(filename, function(exists) { if(exists) { fs.readFile(filename, function(err, data) { response.writeHead(200); response.end(data); }); } else { sys.log('File not found: ' + filename); response.writeHead(404); response.end(); } }); }).listen(port);
file-server.js
Thursday, April 19, 12
Concurrency Level: Time taken for tests: Complete requests: Failed requests: Write errors: Keep-Alive requests: Total transferred: HTML transferred: Requests per second: Time per request: Time per request: Transfer rate:
100 6.000 seconds 10000 0 0 0 710781 bytes 150165 bytes 1666.72 [#/sec] (mean) 59.998 [ms] (mean) 0.600 [ms] (mean, across all concurrent requests) 115.69 [Kbytes/sec] received
Connection Times (ms) min mean[+/-sd] median Connect: 0 8 8.3 5 Processing: 1 51 44.4 40 Waiting: 0 43 43.5 30 Total: 1 59 44.8 50
Percentage of the requests served within a certain time (ms) 50% 50 66% 58 75% 68 80% 73 90% 112 95% 174 98% 206 99% 224 100% 316 (longest request)
http.createServer(function(request, response) { var uri = url.parse(request.url).pathname; var filename = path.join(process.cwd(), dir, uri); path.exists(filename, function(exists) { if(exists) { f = fs.createReadStream(filename); f.on('open', function() { response.writeHead(200); }); f.on('data', function(chunk) { response.write(chunk); }); f.on('error', function(err) { // ... }); f.on('end', function() { response.end(); }); } else { response.writeHead(404); response.end(); }
}); }).listen(port);
stream-file-server.js
Thursday, April 19, 12
var options = function(request) { // ... } http.createServer(function(request, response) { sys.log("--> " + request.url); var remoteRequest = http.request(options(request), function (remoteResponse) { response.writeHead(remoteResponse.statusCode, remoteResponse.headers); remoteResponse.on('data', function (chunk) { response.write(chunk); }); remoteResponse.on('end', function () { sys.log("<-- " + response.statusCode + " " + request.url); response.end(); }); }); request.on('data', function (chunk) { remoteRequest.write(chunk); }); request.on('end', function () { remoteRequest.end(); }); }).listen(port);
proxy.js
Thursday, April 19, 12
http.createServer(function(request, response) { sys.log("--> " + request.url); var remoteRequest = http.request(options(request), function (remoteResponse) { response.writeHead(remoteResponse.statusCode, remoteResponse.headers); remoteResponse.on('end', function () { sys.log("<-- " + response.statusCode + " " + request.url); }); util.pump(remoteResponse, response); }); util.pump(request, remoteRequest); }).listen(port);
proxy-pump.js
Thursday, April 19, 12
Node.js: Kernkonzepte
Async I/O Events & Callbacks Single Process Model
Node.js: Praxistauglichkeit
Sehr jung, aber sehr aktiv Web 2.0-Umfeld Hufig: Vereinfachung
Node.js: Java-Bibliotheken
java.nio java.nio2 Netty (http://www.jboss.org/netty) Grizzly (http://grizzly.java.net/) Vert.x (https://github.com/purplefox/vert.x) Project Nashorn
Fazit
Q&A
Q&A