
Show HN: Golongpoll – Go HTTP longpolling library - jcuga
https://github.com/jcuga/golongpoll
======
RyanZAG
_> Why does everyone run to websockets even when they only need server-to-
client pushing? Probably because it's difficult to get longpolling right._

Definitely not. Longpolling adds a huge amount of overhead when messages are
sent relatively frequently. For each longpoll request, the client needs to
send all the headers and cookies every time. Each response includes all
headers and connection setup. A websocket connection has zero overhead after
the initial http upgrade. If you have websocket available, you should always
prefer websocket to long polling. In most cases where websocket would be
blocked by infrastructure, long polling would be forced to retry extremely
quickly because of forced timeout.

~~~
jkarneges
WebSockets are superior from a technical perspective, no arguing that. But,
long-polling makes for more straightforward APIs, which could be valuable if
you're more concerned about developer UX than the number of bytes on the wire.

For example, long-polling can actually be RESTful, so it fits in well with
conventional API practices. It's also naturally resilient to network issues
since each re-poll heals the stream. Users are very unlikely to lose data due
to forgetting about some corner case.

~~~
RyanZAG
Websockets can be RESTful too. I've seen the following:

    
    
      GET /orders - fetch all orders
      GET /orders Upgrade: websocket - streaming view of all new orders
    

The problem with this type of RESTful integration though is the connection
limit imposed by browsers. Of course, long poll has the identical problem. You
can't long poll more than a couple endpoints.

~~~
jkarneges
True, you can use URI paths with WebSockets which at least makes the streams
resource-oriented. CBIX does it: [https://www.cbix.ca/api-
websocket](https://www.cbix.ca/api-websocket)

I think calling this _RESTful_ is a bit of a stretch though, at least in any
conventional sense of what that means to people.

------
jondubois
Long polling is a hack. Anyone who has had to scale it across more than a
single CPU core on a single machine will know this.

TCP and WebSockets are stateful, HTTP is stateless. So long polling is
essentially:

Stateful -> Stateless -> Sateful

You start in a good place, then you add complexity to make it stateless and
then you add even more complexity to roll back the statelessness and then you
end up where you started... Except it's 90% slower and you now have to use an
armada of sticky load balancers to prevent the system from falling apart...

~~~
regecks
Maybe in "fat" language runtimes this is a problem (Ruby, Java, Python etc).

In Go, requests are a single goroutine, dirt cheap (no problem with a single
CPU). To me, this type of work is where Go excels.

I used SSE (not quite long polling but I think it has the same implications as
far as this discussion goes) back in Go 1.3 days (so GOMAXPROCS=1) to write
metrics to 100<n<1000 clients and the process barely registered CPU or memory
usage. No lock problems either (copying metric values over channels).

As far as complexity .. well, sure, if you fuck up the design or use the wrong
tool for the job you'll have problems.

------
jcuga
When I needed some simple push notifications, I could't find any decent
library or example for longpolling in go (or most other languages), so I
decided to make one :)

A lot of the examples out there in blog posts are too simplistic. They don't
handle buffering old events and most of them simply give an event to the first
request and then discard it. That's not real pub-sub.

~~~
mholt
I'm pretty sure my blog post with a long polling tutorial was one of those.
Glad to see someone improve on the idea and turn it into a lib!

------
jkarneges
Great to see this. I am a big fan of long-polling. Too many people only think
of it as some hack underlying libraries like Socket.io or SockJS, but this is
because they've not seen how clean a long-polling API can actually be.

~~~
jcuga
Yeah. I originally started out using SSE but I ended up settling on
longpolling because of wider browser support and the fact that there are
issues with SSE even on newer browsers and polyfills. The knee-jerk reaction
nowadays is to use websockets for everything, but sometimes simple is better.

~~~
bittersweet
I've been using SSE with Go for personal projects, so just one browser, could
you expand on the issues you mentioned? I'm curious if it is indeed as bad as
you say.

~~~
regecks
Doesn't work in IE, last I checked.

