Yes, Orbited will terminate its end of the connection and reclaim
resources. If you find cases where it doesn't, those are bugs.
> For [bad guys wasting your resources, eating all your file handles],
> possibly an authentication payload sent to the Orbited
> server inside the request to establish the Comet connection gets
> forwarded from Orbited to a/the backend application server. It then
> responds with accept or deny. accept sets up as expected, and deny
> results in the Orbited server closing the connection. Actually I
> think you can do this without change to the client, the Orbited server
> can just ask the application server using the user id and number,
> since the app server will be aware of what user ids and session
> numbers it doled out and which it didn't.
One potential problem with such a solution is that it sort of depends
on an event-based application server, and complexifies porting ORBIT
clients. I also wonder whether this attack would be particularly
worse on the server than just repeatedly opening and closing
connections as fast as possible; we should benchmark it I suppose, but
it is not clear to me that open file handles will be as much a
bottleneck as CPU and bandwidth, here.
-Jacob
The ORBIT protocol (i.e. the capability to *send* events) definitely
shouldn't be exposed to the general internet.
But I don't really see Comet communications being much more attackable
than any other type. Your firewall is better equipt to handle such
vulnerabilities than any authentication of the kind you suggest built
into Orbited, which would additionally at least double the complexity
of Orbited–app communications, and take not insignificant server
processing time to deal with (every connection from a browser must
first be checked with the app).
We need to do some benchmarking to figure out exactly how many idle
connections an Orbited node can handle, etc., but I don't think
idle-connection DDOS attacks against Orbited will be a significant
problem, and adding per-connection checking is as likely to aggravate
as improve matters.
So to summarize, IMO such constraints are better placed in a layer
outside Orbited itself, such as in your interaction-throttling firewall.
-Jacob
We need to do some benchmarking to figure out exactly how many idle
connections an Orbited node can handle, etc., but I don't think
idle-connection DDOS attacks against Orbited will be a significant
problem, and adding per-connection checking is as likely to aggravate
as improve matters.
I think that would be a beneficial step in the right direction.
IMHO, one of the most important things to consider as Orbited develops
is simplicity. In keeping with the Zen of Python, I think it's
critical to consider various possibilities and whittle those down
until you're left with the best way forward.
Orbited, as a simple event-delivery system (as I originally met it
back at 0.2), is architecturally great: I think that design is worth
merit. Where it _can_ get complicated is when we need something more
than just blind event delivery. Again, the more we think through the
problem to come up with the best solution, the better off Orbit (and
comet in general) will be in the future.
Related to connection notification: The more I think about it, a full
connection and disconnection notification system, integrated with
Orbited, would be quite complex.
As opposed to an event-based server. A synchronous app does blocking
I/O, and can't call a callback based on information coming back over
the ORBIT protocol. So it would need another mechanizm. Which leaves
us with different mechanisms depending on the type of app server.
> benefit decision. (no point in spending a lot of resources to save a
> few -- that would make a worse attack vector, wouldn't it?)
Yes, that's exactly right. :)
> > Most app developers are using frameworks like rails or
> > django that provide no mechanism for app-side callback authentication.
>
> Sure, if they just added another page in their framework, (less
> efficient than a direct connection), but the Orbited server could just
> call that Ruby on Rails page or whatever (which could be specified in
> the configuration file) the Orbited server would pass it the ID in
This strikes me as complex, counter-intuitive, and somewhat fragile,
but it might work.
-Jacob
events, so it can't be certain that it knows all clients which have
connected to Orbited. (Unless there's an external authentication
mechanism, which would therefore _require_ that an Application Server
receive those notifications, which IMO is a different, separate
concern.)
The biggest problem I've had with Orbited, which I have not found an
elegant solution to, is how to have the Application Server know when
clients are active.
I don't think it's possible for Orbited to *both* reliably notify an
application server about connections/disconnections *and* scale
effectively, primarily because the moment you couple the Orbit node to
an Application server, you lose the properties of Orbit that
distinguish it from the other Comet apps: Elegant -- effectively
linear -- scalability, thanks to the decoupling of the Comet layer
from the Application layer.
Take a simple chat server: Unless a client "pings" the Application
server regularly to tell the Application server that the client is
still "connected", there isn't a way for the Application server to
know whether or not that client is active unless Orbited can tell the
Application server that that specific client has connected. So how do
you determine when a user has left the chat room? By either the client
explicitly sending a "PART" message, or by an Application-Server-
induced ping timeout. (That's what differentiates UDP from TCP...
that's essentially what we're working with in terms of client-to-
server requests for an application server over HTTP.)
But the problem with pings to the Application Server is this: Imagine
1000 clients, pinging an Application Server every 30 seconds. That's
2000 requests a minute -- 33 requests a second. That's a huge load for
such a relatively small number of connections. 66 requests a second
for 2000 connections... and it only gets worse.
Session _creation_ is dead-simple. The first time a client talks to
the application server, the application server knows it's available.
The only reason we need pings is to detect when a client *disconnects*.
If the connection/notification mechanism (as I was trying to describe
in that graphic) is added to Orbited, it provides a way for the
Application Server to track disconnections. However, there are a few
concerns:
- What if the application server becomes disconnected from Orbited,
and during that time a client disconnects from Orbited? The
application would miss the notification, and the Application would
forever think that the client was still connected.
- A workaround for that would be for Orbited to implement a queuing
mechanism to ensure reliable delivery of all connection and
disconnection messages, for any and all application servers which
request that capability. (But that's just a by-the-book message
queue... it seems that would be better suited to an application-
dependent message queuing or pub-sub layer...)
Bah. All-in-all, I guess this can be summarized in two paragraphs:
To track client connection status, one must implement pinging to the
Application server, which (from the numbers I've calculated) could
take a heavy toll on performance of an app server.
Alternatively, Michael has mentioned that Orbited will be getting a
connection/disconnection notification mechanism, which _could_ solve
some of those problems, but I'd be interested in knowing if that will
be a reliable delivery mechanism or not. If it's reliable, I suppose
that could be leveraged effectively -- but if it's not reliable, it
wouldn't do much good in the situation where the App Server(s) could
temporarily lose their connection to the Orbited node(s).
IMHO, the more distinct we can keep the tiers of an application, the
better.
Now that I've hashed that all out in my head, I'm actually a lot
clearer on how a *reliable* connection-notification facility in
Orbited *could* be feasible without overcomplicating matters. But I'm
still uncertain as to whether or not that would be the best solution
-- and whether or not such a feature should be in the Orbited layer.
I mean i understand synchronous communication, but wasn't sure in this
On Jan 24, 1:11 am, "Jacob Rus" <jacobo...@gmail.com> wrote:
> Kevin Livingston wrote:
> > > 2) What if the application is using ORBIT protocol as a synchronous
> > > protocol? how does it handle callbacks?
> > I guess I'm not really sure of the distinction here?
> As opposed to an event-based server. A synchronous app does blocking
> I/O, and can't call a callback based on information coming back over
> the ORBIT protocol. So it would need another mechanizm. Which leaves
> us with different mechanisms depending on the type of app server.
context. So to give this a concrete example, we're talking about
something like a single threaded application server? Then yes there
could be some complicated situation which might lead to deadlocks,
which I thought about before, but then promptly forgot about. But I
think then the Orbited callbacks could just get interleaved into the
single event queue, and I think the order would be such that deadlock
would not be created.
Thanks.
> I would be much more willing to put a HTTP callback mechanism in
> Orbited than change the protocol because it would keep everythign
> simple still and the ORBIT protocol would continue to be backwards
> compatabile (a minor issue only.) But most importantly, its the
> first semi-sensible way of creating real-time web applications with
> synchronous app servers that I've yet considered. The major concern
> would be mapping Orbited nodes to app nodes for the purpose of
> scaling. But at worst we could start with a A-B config based mapping
> mechanism.
Yes, an HTTP callback could be one way of doing it. That would be the
only reasonable way to do it with synchronous frameworks I think, but
I wouldn't be a fan of using that when you have asynchronous
frameworks; that would require an asynchronous app to learn the HTTP
protocol, and if the App server (or Orbit) doesn't know about keep-
alive, there'd be a pretty big overhead for each notification.
In the case of multiple Application Server / Orbited nodes:
Just like it's the Application Servers' responsibility to determine
which Orbit node(s) to communicate with (i.e. via client-token
hashing), I think it also falls within the scope of the Application
Server to notify Orbit about what types of events it wants to receive.
If an Application node wanted to receive connect/disconnect
notifications, it could specify so when it connects to Orbited. If
there are multiple App nodes connected to the Orbit node, the
Application Server would need to be aware that BOTH nodes would
receive notification (it would need to discard one), unless only *one*
of the app servers explicitly requested notification. Alternatively,
Orbit could implement a type of notification where it will just send
the notification to ONE of the nodes, even if there are multiple nodes
connected.
If it was done that way, a distributed application could choose to
select one node to be a "notification handler" -- that node could
handle ALL notifications while never sending _any_ events to Orbited
itself. That would be useful if it wanted to push the notifications
onto the distributed application's message queuing system.
On a related note:
The easier it is for clients to implement Orbited, the greater chance
Orbited has for widespread adoption. If the "ORBIT/advanced" protocol
is homegrown, custom clients will need to be written for every target
language; this has the advantage that the protocol is completely
tailored to our needs, but at the cost of interoperability.
Have you seen STOMP? (http://stomp.codehaus.org/) STOMP is a text-
based protocol used with Message Queue software, and there are
numerous clients in different languages for it. Its protocol reminds
me very much of Orbited's protocol: simple and HTTP-like. I think it
would be worth considering whether or not Orbited would benefit from
using *that* protocol -- if it did, we'd instantly have clients done
and written in 12 languages.
That's just a thought, but I would strongly encourage you to at least
look at such a possibility. By reusing a protocol like STOMP, we get
immense interoperability and a much shallower curve of entry for
different programming languages. I think that alone would be worth the
consideration, not to mention the other benefits of using a standard
protocol.
I forget where, but I read a story not too long ago where someone
implemented a Message Queue system over Memcached's protocol: They
instantly had the advantage that they could use _any_ of the already-
created Memcached clients to dispatch messages; that seems like a huge
benefit.
Maybe it wouldn't work, but I think it's worth an investigation. The
potential benefits are strong and IMHO worth consideration.
Marcus
Have you seen STOMP? (http://stomp.codehaus.org/) STOMP is a text-
based protocol used with Message Queue software, and there are
numerous clients in different languages for it. Its protocol reminds
me very much of Orbited's protocol: simple and HTTP-like. I think it
would be worth considering whether or not Orbited would benefit from
using *that* protocol -- if it did, we'd instantly have clients done
and written in 12 languages.
That's just a thought, but I would strongly encourage you to at least
look at such a possibility. By reusing a protocol like STOMP, we get
immense interoperability and a much shallower curve of entry for
different programming languages. I think that alone would be worth the
consideration, not to mention the other benefits of using a standard
protocol.
You're right; a STOMP-based Orbit protocol would need to give some
type of semantic meaning (e.g. recipients names are separated via
commas or something), so it couldn't be used verbatim.
> 2) the Reicept frame is used to acknowledge that the server received
> a particular command, but not the outcome of the command. In fact,
> there is no good way of returning a 'success' or 'failure' of a
> particular command. There is an error message type, but it contains
> NO provisions for specifiying in the protocol what particular
> command caused the error. It seems to be used to report malformed
> requests more than anything.
Also a good point. The server could probably behave differently, but
you'd have to make sure the clients are OK with that behavior.
Given those considerations, I think you're right that STOMP wouldn't
be a very good fit for the Orbited server. It's close, but some
nuances mean that an equally simple Orbited protocol might make more
sense.
Provided the Orbited protocol remains simple, straightforward, and
consistent, while keeping room for extensibility in the future, I
suppose a homegrown protocol would be fine... especially since the
Orbited protocol is used somewhat internally to an application rather
than as a public-facing interface.
Sure, I'd be up for working on that. Let me know where to start and
I'll take a look.