Continuations (Jetty

Continuations (Jetty

COMET: –

COMET: –

. .

COMET – OS

(Twisted, node.js, …)

Continuations (Jetty, GlassFish…)

(Erlang, Stackless Python…)

COMET- Java, Javascript, Python, Erlang.

, , , .

, , , :

, .

.

– .

, , (), , .

, , 20 , : , 5 30, .

, , ..

pre-fork, , – .

FastCGI: PHP/FastCGI, Perl/FastCGI, Ruby/FastCGI . WSGI(Python), .

– , . – , , , .

, .

– – : . .

, ( , ..) , .

, , , ..

– , . .

, – , .

, , (, – ), , .

, , PHP .

– , , . : , , , .

, . , – .

– . , .

:

// include MyFramework; MyFramework::init(); // while , while(request = FastCGI::accept()) MyFramework::process(request);

MyFramework::process(request) , .

request , . – .

? ! , , , Perl/FastCGI, Ruby/FastCGI.

, , . , .

– .

, , .

, , .

– , print counter . , – , counter++print counter. – .

– : , , ..

: counter :

process , – , . counter .

, , , .. , , .

, . , ..

– , , . , .

– – (Java): Tomcat, Resin . Servlet API 2.5. .

COMET- , .

( )

,

( )

, . – , – .

100 100 ( ), . , , .

1000, 10.000 , , : , -, .

COMET-, .

, , – , .

javascript:

xhr.send() , . XmlHttpRequest, onreadystatechange- processResult.

. COMET-, Twisted ( Python).

COMET- long-poll. :/publish/subscribe.

/subscribe , . – .

/publish message , .

class ClientManager: clients = [] def registerClient(self, client): self.clients.append(client) def broadcastMessage(self, message): for client in self.clients: client.write(message) client.finish() self.clients = [] clientManager = ClientManager() class CometServer(resource.Resource): isLeaf = False def __init__(self): resource.Resource.__init__(self) self.registerChildren() def registerChildren(self): self.putChild(subscribe, Subscribe() ) self.putChild(publish, Publish() ) def getChild( self, path, req ): if path == : return self else: return resource.Resource.getChild( self, path, req ) class Subscribe(resource.Resource): isLeaf = True def render_GET(self, req): clientManager.registerClient(req) return server.NOT_DONE_YET class Publish(resource.Resource): isLeaf = True def render_POST(self, req): clientManager.broadcastMessage(req.args[message][0]) return ok application = service.Application(App) service = internet.TCPServer(8001, server.Site(CometServer())) service.setServiceParent(application)

:

ClientManager -, clients.

registerClient broadcastMessage.

CometServer -, . Twisted.web Subscribe()Publish(), .

Subscribe . /subscribe, ( ) . server.NOT_DONE_YET, , Twisted .

, clientManager.

Publish POST-, message .

Publish . .

/.

.

, , clientManager.clients, .

, . , ..

, .

, – , .

, , API . .

, , . , , .

– .

– , Twisted (adbapi ) , :

, , deferToThread:

deferred Deferred , addCallback, .

– , .

, .. , , , , .

. , .

– . Python, , Global Interpreter Lock, .

, ( thread-safe) .

– , . .

– , , .. : , , .

Node.JS Javascript V8 Javascript- libev . . /.

COMET- Node.JS:

sys = require(sys), http = require(http); url = require(url) clientManager = new function() var clients = [] this.registerClient = function(client) clients.push(client) this.broadcastMessage = function(message) for(var i=0; iclients.length; i++) var client = clients[i] client.writeHeader(200, Content-Type: text/plain;charset=utf-8) client.write(message.toString(), utf-8) client.close() clients = [] http.createServer(function (req, res) var urlParsed = url.parse(req.url, true) if (urlParsed.pathname == /publish) ssage) res.writeHeader(200, Content-Type: text/plain;charset=utf-8) res.write(ok, utf-8) res.close() if (urlParsed.pathname == /subscribe) clientManager.registerClient(res) ).listen(8000);

, Node.JS Twisted . clientManager. .

Node.JS Twisted, , .

– Jetty, Java.

, Continuation, .

, , continuation.resume(), , continuation .

public class SubscribeServlet extends HttpServlet protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException Continuation continuation = ContinuationSupport.getContinuation(req); if (continuation.isInitial()) continuation.suspend(); ClientManager.getInstance().registerClient(continuation); else String message = (String)continuation.getAttribute(message); resp.setContentType(text/plain;charset=utf-8); resp.getWriter().print(message);

continuation.suspend(); ClientManager.getInstance().registerClient(continuation);

,

, – .

.

/publish. PublishServlet:

public class PublishServlet extends HttpServlet protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException ClientManager.getInstance().broadcastMessage(req.getParameter(message)); resp.setContentType(text/plain;charset=utf-8); resp.getWriter().print(ok);

ClientManagerbroadcastMessage, :

public class ClientManager ArrayListContinuation continuations = new ArrayListContinuation(); public synchronized void registerClient(Continuation continuation) continuations.add(continuation); public synchronized void broadcastMessage(String message) for(Continuation continuation: continuations) continuation.setAttribute(message, message); continuation.resume(); continuations.clear(); // private static ClientManager ourInstance = new ClientManager(); public static ClientManager getInstance() return ourInstance; private ClientManager()

, .

, Continuation, continuations. ArrayList, thread-safe.

broadcastMessage continuations ( ) continuation.resume().

, continuation, . continuation.isInitial() false, .. .

SubscribeServlet :

continuation.suspend(), .

, clientManager , .. synchronized. , .

Continuations , .

, continuation.resume()broadcastMessage , continuation.

, , :

continuation.resume(); – , , , – .

, ..

, : .

GlassFish Servlet API 3.0.

ThreadPool. , , , .

ontinuation . .

/CPU.

( continuations) .

.

– . , , , 100, 1000, 10.000 .

OS . .

, , Erlang.

, , , .

COMET- MochiWeb.

room(Users) – receive From, subscribe – From ! subscribed, room([From Users]); From, post, Message – From ! posted, lists:foreach(fun(User) – % broadcast the message User ! Message end, Users), room([]); _Any – room(Users) end. get_the_room() – % does the room exists? Pid = whereis(theroom), if is_pid(Pid) – % yup Pid; true – % create it NewPid = spawn(fun() – room([]) end), register(theroom, NewPid), NewPid end. loop(Req, DocRoot) – / ++ Path = Req:get(path), case Req:get(method) of Method when Method =:= GET; Method =:= HEAD – case Path of subscribe – Room = get_the_room(), Room ! self(), subscribe, receive subscribed – % subscription is ok % now wait for a message receive Message – ok after ?TIMEOUT – % we waited too long Message = timeout end after 50000 – % subscription failed on time Message = timeout end, % send back the JSON message Req:ok(text/plain;charset=utf-8, Message); end; POST – case Path of publish – Data = Req:parse_post(), Room = get_the_room(), % post Room ! self(), post, list_to_binary(proplists:get_value(message, Data)), receive posted – % posted ok after 50000 – % something went wrong notok end, % send back the message Req:ok(text/plain, ok); _ – Req:not_found() end; _ – Req:respond(501, [], []) end.

, – .

. . .

. . .

Erlang , .

, .

theroom. clientManager, .

get_the_room Pid theroom, , spawn.

get_the_room() – % does the room exists? Pid = whereis(theroom), if is_pid(Pid) – % yup Pid; true – % create it NewPid = spawn(fun() – room([]) end), register(theroom, NewPid), NewPid end.

– theroom. room.

room- . spawn .

room(Users) – *!*receive*/!* From, subscribe – From ! subscribed, room([From Users]); From, post, Message – From ! posted, lists:foreach(fun(User) – % broadcast the message User ! Message end, Users), room([]); _Any – room(Users) end.

receive , .

subscribe From, subscribed:

, .. , room([From Users])- , , From( ).

receive . , – .

From, post, Message post .

, .

, , , , – .

, , (-, subscribe) , (-, post, -)- , – _Any.

room([]) , .

. , subscribepublish.

% Room = get_the_room(), % subscribe () Room ! self(), subscribe, % receive subscribed – % , receive Message – ok % after ?TIMEOUT – % Message = timeout end after 50000 – % Message = timeout end, % Req:ok(text/plain;charset=utf-8, Message);

publish , .

, 100, 1000 100.000 Erlang/OTP.

Continuations.

(hibernate), , .

, , .

, .. hibernate, , , .

, , ( ), Erlang , .

.

Linux nf:

General gigabit tuning: net.core.rmem_max = 16777216 net.core.wmem_max = 16777216 net.ipv4.tcp_rmem = 4096 87380 16777216 net.ipv4.tcp_wmem = 4096 65536 16777216 net.ipv4.tcp_syncookies = 1 this gives the kernel more memory for tcp which you need with many (100k+) open socket connections net.ipv4.tcp_mem = 50576 64768 98152 net.core.netdev_max_backlog = 2500 net.ipv4.tcp_keepalive_time = 300 net.core.somaxconn = 4096

– . , root: (/etc/security/limits.conf)

, , .

, COMET, javascript- : polling / streaming / long-poll.

:

Java – Continuations, Python/Ruby/Javascript – , Erlang- hibernate.

, Java- – CPU, Python/Ruby/Javascript – , Erlang , .

, .

, . – …

Rutwit . (, ) ?

, Node.js (, , Plurk ).

, .

P.S. , .

P.P.S. , Java Comet- Atmosphere (

COMET- . , – .

, ( ) . .

, – () COMET, . , – .

Java?

framework`.

. orbited pooling, long-pooling, Callback-Polling, Iframe Streaming, HTML5 WebSocket ( ? ?

APE long pooling, 100k .

comet ?

, , . , ..

, long polling … , – .

PHP COMET-? – [PHP] , .

phpDaemon .

. COMET Node.js, . subscribe publish, subscribe. subscribe- . , .

, , . : . ok, foo. publish, . .. . , – , publish…

( ).

, , , . . , Chrome , subscribe , publish.

, links.

– . , node.js ( , , ). , , . , .

Ajax – .

COMET: –

, COMET

XMLHTTPRequest, interactive

. 2.

Javascript

: , , Boolean

. .

javascript- 7

Ajax – .

. 2.

Yahoo:

Javascript-.

Javascript/CSS

a href=javascript:… –

– Selenium + PHP.

Google Closure Library

. DOM Storage .

DIV

. ?

DevTools – ?

checkbox .checked

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注