Websockets without hogging CPU?

698 views
Skip to first unread message

Paddy Foran

unread,
Nov 19, 2011, 9:31:46 AM11/19/11
to golan...@googlegroups.com
Sorry to post two questions in short succession, but I just noticed a cause for some concern.

Apparently, the best way to handle WebSockets is to use channels, goroutines, and two ever-spinning for loops. (http://gary.beagledreams.com/page/go-websocket-chat.html) Or so I've been told.

There is only one small problem with this: When I do that, the program becomes a major CPU hog. When I noticed, it was consuming 95% of my CPU in 9 threads with 10.6mb in memory. One of these numbers does not match the others.

I'm assuming the devouring of all available CPU comes from the fact that I'm telling two loops to run as fast as they can for forever. My question is, how can I serve websockets without devoting every spare cycle to maintaining pub/sub status?

Thanks,
Paddy Foran

Paddy Foran

unread,
Nov 19, 2011, 11:33:14 AM11/19/11
to golan...@googlegroups.com
Hi Gary,

Thanks for the reply (and the example!). I can verify that my CPU usage is being caused by the loops. On the page's first load, the loops work as you describe. If I refresh the page, however, the loops execute as fast as they can, repeating, and my CPU usage immediately spikes to 100%. I'm not sure what to attribute the discrepancy to-- of course, I am using a heavily modified version of the example. You can see my version here: https://github.com/secondbit/Bessie/blob/http/twocloud/websockets.go

The output I'm getting is:
2011/11/19 11:24:32 looping in hub
2011/11/19 11:24:32 looping in hub
2011/11/19 11:24:32 looping in wsHandler
2011/11/19 11:24:32 looping in wsHandler
2011/11/19 11:24:32 looping in hub
2011/11/19 11:24:32 looping in hub
2011/11/19 11:24:32 looping in wsHandler
2011/11/19 11:24:32 looping in wsHandler
[etc.]

My best guess is that I've altered the example to use websocket.JSON.Receive instead of the buffer your example has. I could be entirely wrong, though; I'm grasping at straws. Any insight would be greatly appreciated.

Thanks,
Paddy Foran


On Sat, Nov 19, 2011 at 11:16 AM, gary b <gary...@gmail.com> wrote:
> telling two loops to run as fast as they can for forever.

The two loops in the example block waiting for input. The loops only consume CPU when a user sends a chat message.

Add logging to the loops to determine if they are spinning independent of user input.

Jesse McNelis

unread,
Nov 19, 2011, 11:59:48 AM11/19/11
to Paddy Foran, golan...@googlegroups.com
On 20/11/11 03:33, Paddy Foran wrote:
> https://github.com/secondbit/Bessie/blob/http/twocloud/websockets.go

> My best guess is that I've altered the example to use
> websocket.JSON.Receive instead of the buffer your example has. I could
> be entirely wrong, though; I'm grasping at straws. Any insight would be
> greatly appreciated.

You're calling,
websocket.JSON.Receive(ws, &data)

but you're not checking for the error value that it returns.

I imagine it's erroring every time it's called so the loop never blocks.

- jessta

Paddy Foran

unread,
Nov 19, 2011, 12:07:28 PM11/19/11
to jes...@jessta.id.au, gary...@gmail.com, golan...@googlegroups.com
Fun fact: I didn't even realise websocket.JSON.Receive could throw an error. That'll teach me to look further than the trivial usage in the documentation. Catching the error, checking if nil, and breaking on nil fixed the issue. Now to figure out exactly what errors are being thrown, to make sure something doesn't bite me later on...

Thanks for the help! I really appreciate it. On a side note: is it just me, or are a lot of Go issues caused by not checking for errors?

Thanks,
Paddy Foran

Jan Mercl

unread,
Nov 19, 2011, 12:10:52 PM11/19/11
to golan...@googlegroups.com
On Saturday, November 19, 2011 6:07:28 PM UTC+1, Paddy Foran wrote:
Thanks for the help! I really appreciate it. On a side note: is it just me, or are a lot of Go issues caused by not checking for errors?

A lot of programmer's issues are caused by not checking for returned errors.

Paddy Foran

unread,
Nov 19, 2011, 12:27:19 PM11/19/11
to golan...@googlegroups.com
Of course. I didn't mean to imply this was somehow a weakness or problem in the language (quite the opposite, in fact). I just see a lot of answers that boil down to "catch your errors", and even knowing this common error, I still face-first into it. On the bright side, it was a fix that took me about thirty seconds to implement, once I knew where it was. Not many languages can boast that. Had it been what I feared (that I couldn't use the for loops), it would've taken major restructuring and quite a few headaches. I'm pretty happy the answer boils down to "stop doing that dumb thing right there."

Thanks,
Paddy Foran
Reply all
Reply to author
Forward
Message has been deleted
Message has been deleted
0 new messages