(Migrated) Long Polling over HTTPS

(This message has been automatically imported from the retired mailing list)

Hello,

First, you have put together a beautiful project here, very impressive.
Second, I am in the evaluation stages with Zatos and am trying to determine
how it would help solve our various messaging problems. Currently we have a
requirement for a handful of .NET client/server installations to act as a
service from within on-premise app servers usually running behind our
clients firewalls that can communicate with our apps running in the cloud.

The .NET app can already post outbound events to HTTP endpoints, but we now
need the .net app to participate in a more bi-directional way, and because
we aren=B9t usually in control of the network where this app is installed I=B9d
prefer the transport layer to =B3just work=B2 to the maximum extent possible
regardless of firewall configurations. Since our .net app already uses HTTP=
S
that seems like the way to go. We could use something like AWS SQS or
IronQueue, but since Zatos doesn=B9t have native channels for those message
queues and they will require manual administration and configuration I was
thinking it might be simpler just expose a vanilla Zatos service via HTTP
and use long polling to provide reasonably low latency push to the .NET app=
,
probably bridging an AMQP queue hosted inside our Rackspace cloud.

So first, does that seem reasonable in general? And second, is that
something Zatos would have any issues with, holding an HTTP connection open
for some period (say 20/30 seconds)? We=B9re mostly a ruby shop so I don=B9t
know much about gunicorn, but I believe I read that you are using its
evented workers, so I presume we wouldn=B9t starve the server of worker
processes using this approach? Are there any other Zatos specific caveats?
And when the .net app replies to a message it receives in this way (by
posting to another endpoint over HTTPS) can the reply be easily correlated
to the original request?

Thank you for your time,

Nathan

Dariusz,

Thank you for the detailed answer, you certainly answered all of my
questions. As you said, HTTP Pub/Sub won=B9t work in this particular case,
but that sounds like an incredibly useful feature, I didn=B9t see that in
the docs - is there a doc on it that I missed, or a place in the source
code that we should check out? I can see that being huge for us.

Thank you again,

Nathan

On 12/31/14, 8:04 AM, “Dariusz Suchojad” dsuch@zato.io wrote:

On 31/12/14 00:01, Nathan Stults wrote:

I was thinking it might be simpler just expose a vanilla Zatos service
via HTTP and use long polling to provide reasonably low latency push to
the .NET app, probably bridging an AMQP queue hosted inside our
Rackspace cloud.
=20
So first, does that seem reasonable in general? And second, is that
something Zatos would have any issues with, holding an HTTP connection
open for some period (say 20/30 seconds)? We=B9re mostly a ruby shop so I
don=B9t know much about gunicorn, but I believe I read that you are using
its evented workers, so I presume we wouldn=B9t starve the server of
worker processes using this approach? Are there any other Zatos specific
caveats? And when the .net app replies to a message it receives in this
way (by posting to another endpoint over HTTPS) can the reply be easily
correlated to the original request?

Hi Nathan,

thanks for your nice words, it’s cool you find the project interesting.

As you’ll recall from the architecture’s overview …

https://zato.io/docs/architecture/overview.html

… there’s a HAProxy-based load-balancer in front of servers so the
question could be reworded into whether the LB can handle a lot of open
connections. The answer is yes because it uses libevent. Servers,
accidentally, use libev through gunicorn and gevent. So both parts are
happy to withstand a lot of open connections from TCP clients.

How long given connections - from clients to LB, from LB to servers -
should be kept before giving up is configured here:

https://zato.io/docs/web-admin/load-balancer/gui.html#frontend-config

As for correlating requests and responses, this is where the CID
(Correlation ID) is used:

https://zato.io/docs/progguide/service-dev.html#cid

This value is assigned automatically as soon as a request comes in, is
used throughout the whole life of a service’s invocation, for instance
in HTTP logs …

127.0.0.1 K059SX2TRXRGWSRTCDFK6M28HW7D/0.067553 “My Channel”
[14/Dec/2014:23:32:25 +0100] “GET /mychannel HTTP/1.0” 200 0 “-”
“ApacheBench/2.3”

… or in any exception messages, and it’s also returned to callers in
the X-Zato-CID HTTP header:

$ curl -v localhost:17010/zato/ping ; echo

  • Hostname was NOT found in DNS cache
  • Trying 127.0.0.1…
  • Connected to localhost (127.0.0.1) port 17010 (#0)

GET /zato/ping HTTP/1.1
User-Agent: curl/7.35.0
Host: localhost:17010
Accept: /

< HTTP/1.1 200 OK

  • Server Zato is not blacklisted
    < Server: Zato
    < Date: Wed, 31 Dec 2014 15:56:18 GMT
    < Connection: keep-alive
    < Transfer-Encoding: chunked
    < Content-Type: application/json
    < X-Zato-CID: K0702B2HYGHYZ7MHZH3XGRW2ANY8
    <
  • Connection #0 to host localhost left intact
    {“zato_env”: {“details”: “”, “result”: “ZATO_OK”, “cid”:
    “K0702B2HYGHYZ7MHZH3XGRW2ANY8”}, “zato_ping_response”: {“pong”: “zato”}}
    $

Hence the clients can store CIDs of their own requests and ask for
responses to that very CIDs later on, i.e. this is polling.

Zato 2.0 will give you HTTP-based publish/subscribe which lets you
specify callback URLs to invoke on new events in a given topic but you
mentioned you couldn’t control the firewalls so polling sounds like the
best approach - no firewalls to take into account except for the traffic
from clients to the LB.

However, if you are looking for WebSockets then no, this is not
implemented. I can tentatively say this may not be so difficult to
achieve given that HAProxy certainly does support WS but it’s simply not
done yet - will have to wait for 2.1 or later.

I hope this answer your questions or would you like me to go further
into anything in particular?

Very cool, thanks!

Thank you,

Nathan Stults

Sunfish Technology, Inc.
(707) 387-1111
(866) 412-3473
nathan@sunfishtechnology.com

On 12/31/14, 9:56 AM, “Dariusz Suchojad” dsuch@zato.io wrote:

On 31/12/14 18:50, Dariusz Suchojad wrote:

This is part of Zato 2.0 which will be released in January after the
documentation has been completed:

https://zato.io/docs/2.0/
https://zato.io/docs/2.0/project/changelog.html

I forgot to add that you can try it out already using this Dockerfile
which sets up a quickstart cluster running 2.0-pre1:

https://zato.io/downloads-dev-docker.html

On 31/12/14 00:01, Nathan Stults wrote:

I was thinking it might be simpler just expose a vanilla Zatos service
via HTTP and use long polling to provide reasonably low latency push to
the .NET app, probably bridging an AMQP queue hosted inside our
Rackspace cloud.

So first, does that seem reasonable in general? And second, is that
something Zatos would have any issues with, holding an HTTP connection
open for some period (say 20/30 seconds)? We’re mostly a ruby shop so I
don’t know much about gunicorn, but I believe I read that you are using
its evented workers, so I presume we wouldn’t starve the server of
worker processes using this approach? Are there any other Zatos specific
caveats? And when the .net app replies to a message it receives in this
way (by posting to another endpoint over HTTPS) can the reply be easily
correlated to the original request?

Hi Nathan,

thanks for your nice words, it’s cool you find the project interesting.

As you’ll recall from the architecture’s overview …

https://zato.io/docs/architecture/overview.html

… there’s a HAProxy-based load-balancer in front of servers so the
question could be reworded into whether the LB can handle a lot of open
connections. The answer is yes because it uses libevent. Servers,
accidentally, use libev through gunicorn and gevent. So both parts are
happy to withstand a lot of open connections from TCP clients.

How long given connections - from clients to LB, from LB to servers -
should be kept before giving up is configured here:

https://zato.io/docs/web-admin/load-balancer/gui.html#frontend-config

As for correlating requests and responses, this is where the CID
(Correlation ID) is used:

https://zato.io/docs/progguide/service-dev.html#cid

This value is assigned automatically as soon as a request comes in, is
used throughout the whole life of a service’s invocation, for instance
in HTTP logs …

127.0.0.1 K059SX2TRXRGWSRTCDFK6M28HW7D/0.067553 “My Channel”
[14/Dec/2014:23:32:25 +0100] “GET /mychannel HTTP/1.0” 200 0 “-”
“ApacheBench/2.3”

… or in any exception messages, and it’s also returned to callers in
the X-Zato-CID HTTP header:

$ curl -v localhost:17010/zato/ping ; echo

  • Hostname was NOT found in DNS cache
  • Trying 127.0.0.1…
  • Connected to localhost (127.0.0.1) port 17010 (#0)

GET /zato/ping HTTP/1.1
User-Agent: curl/7.35.0
Host: localhost:17010
Accept: /

< HTTP/1.1 200 OK

  • Server Zato is not blacklisted
    < Server: Zato
    < Date: Wed, 31 Dec 2014 15:56:18 GMT
    < Connection: keep-alive
    < Transfer-Encoding: chunked
    < Content-Type: application/json
    < X-Zato-CID: K0702B2HYGHYZ7MHZH3XGRW2ANY8
    <
  • Connection #0 to host localhost left intact
    {“zato_env”: {“details”: “”, “result”: “ZATO_OK”, “cid”:
    “K0702B2HYGHYZ7MHZH3XGRW2ANY8”}, “zato_ping_response”: {“pong”: “zato”}}
    $

Hence the clients can store CIDs of their own requests and ask for
responses to that very CIDs later on, i.e. this is polling.

Zato 2.0 will give you HTTP-based publish/subscribe which lets you
specify callback URLs to invoke on new events in a given topic but you
mentioned you couldn’t control the firewalls so polling sounds like the
best approach - no firewalls to take into account except for the traffic
from clients to the LB.

However, if you are looking for WebSockets then no, this is not
implemented. I can tentatively say this may not be so difficult to
achieve given that HAProxy certainly does support WS but it’s simply not
done yet - will have to wait for 2.1 or later.

I hope this answer your questions or would you like me to go further
into anything in particular?

On 31/12/14 00:01, Nathan Stults wrote:

I was thinking it might be simpler just expose a vanilla Zatos service
via HTTP and use long polling to provide reasonably low latency push to
the .NET app, probably bridging an AMQP queue hosted inside our
Rackspace cloud.

So first, does that seem reasonable in general? And second, is that
something Zatos would have any issues with, holding an HTTP connection
open for some period (say 20/30 seconds)? We’re mostly a ruby shop so I
don’t know much about gunicorn, but I believe I read that you are using
its evented workers, so I presume we wouldn’t starve the server of
worker processes using this approach? Are there any other Zatos specific
caveats? And when the .net app replies to a message it receives in this
way (by posting to another endpoint over HTTPS) can the reply be easily
correlated to the original request?

Hi Nathan,

thanks for your nice words, it’s cool you find the project interesting.

As you’ll recall from the architecture’s overview …

https://zato.io/docs/architecture/overview.html

… there’s a HAProxy-based load-balancer in front of servers so the
question could be reworded into whether the LB can handle a lot of open
connections. The answer is yes because it uses libevent. Servers,
accidentally, use libev through gunicorn and gevent. So both parts are
happy to withstand a lot of open connections from TCP clients.

How long given connections - from clients to LB, from LB to servers -
should be kept before giving up is configured here:

https://zato.io/docs/web-admin/load-balancer/gui.html#frontend-config

As for correlating requests and responses, this is where the CID
(Correlation ID) is used:

https://zato.io/docs/progguide/service-dev.html#cid

This value is assigned automatically as soon as a request comes in, is
used throughout the whole life of a service’s invocation, for instance
in HTTP logs …

127.0.0.1 K059SX2TRXRGWSRTCDFK6M28HW7D/0.067553 “My Channel”
[14/Dec/2014:23:32:25 +0100] “GET /mychannel HTTP/1.0” 200 0 “-”
“ApacheBench/2.3”

… or in any exception messages, and it’s also returned to callers in
the X-Zato-CID HTTP header:

$ curl -v localhost:17010/zato/ping ; echo

  • Hostname was NOT found in DNS cache
  • Trying 127.0.0.1…
  • Connected to localhost (127.0.0.1) port 17010 (#0)

GET /zato/ping HTTP/1.1
User-Agent: curl/7.35.0
Host: localhost:17010
Accept: /

< HTTP/1.1 200 OK

  • Server Zato is not blacklisted
    < Server: Zato
    < Date: Wed, 31 Dec 2014 15:56:18 GMT
    < Connection: keep-alive
    < Transfer-Encoding: chunked
    < Content-Type: application/json
    < X-Zato-CID: K0702B2HYGHYZ7MHZH3XGRW2ANY8
    <
  • Connection #0 to host localhost left intact
    {“zato_env”: {“details”: “”, “result”: “ZATO_OK”, “cid”:
    “K0702B2HYGHYZ7MHZH3XGRW2ANY8”}, “zato_ping_response”: {“pong”: “zato”}}
    $

Hence the clients can store CIDs of their own requests and ask for
responses to that very CIDs later on, i.e. this is polling.

Zato 2.0 will give you HTTP-based publish/subscribe which lets you
specify callback URLs to invoke on new events in a given topic but you
mentioned you couldn’t control the firewalls so polling sounds like the
best approach - no firewalls to take into account except for the traffic
from clients to the LB.

However, if you are looking for WebSockets then no, this is not
implemented. I can tentatively say this may not be so difficult to
achieve given that HAProxy certainly does support WS but it’s simply not
done yet - will have to wait for 2.1 or later.

I hope this answer your questions or would you like me to go further
into anything in particular?

On 31/12/14 17:59, Nathan Stults wrote:

Thank you for the detailed answer, you certainly answered all of my
questions.

Sure, my pleasure.

As you said, HTTP Pub/Sub won¹t work in this particular case,
but that sounds like an incredibly useful feature, I didn¹t see that in
the docs - is there a doc on it that I missed, or a place in the source
code that we should check out? I can see that being huge for us.

This is part of Zato 2.0 which will be released in January after the
documentation has been completed:

https://zato.io/docs/2.0/
https://zato.io/docs/2.0/project/changelog.html

Right now I can offer a few screen-shots …



… though they only depict a few parts of the mechanism.

The whole idea is that you use HTTP to submit messages to topics, which
are implemented on top of Redis, out of which they are directed over
HTTP again to all the consumers subscribed to them. Consumers can either
poll or provide callbacks for Zato to invoke with new messages. Web
admin, apart from the usual CRUD, allows you to browse queues and
confirm what the payload was.

Quite neat stuff with completely different characteristics of messaging
when compared to regular HTTP request/response calls.