HNHacker News
TopNewBestAskShowJobs

windlep

889 karma · joined December 19, 2014

submissionscomments
windlep··on 10M Concurrent Websockets
Yes, exactly. Which is why we switched from Go to Python (using twisted), and dropped our memory use substantially for holding open hundreds of thousands (and soon millions) of websocket connections.

M:N schedulers and the primitives they use for their 'lightweight' threading are always going to use more memory than a single-threaded event loop.

windlep··on Dropbox’s Exodus from the Amazon Cloud
Any plans to open-source the futures-based Rust framework? :)
windlep··on Frameworks Don't Make Much Sense
This ignores the problem of not using a framework, that is, for a sufficiently complex project you will eventually end up with your own ad-hoc framework if you don't use an existing one. Maybe it's better, maybe worse, but one will appear regardless.

That's how Django and Rails started (and I'm sure many more). Ad-hoc frameworks that then get yanked out of the project so the company can re-use the useful parts.

I've seen quite a few ad-hoc frameworks companies have inadvertently created in their effort to "not use a framework", rarely were they nearly as good as what was already out there in the OSS world.

windlep··on A Unicorn Is the Last Thing This Web 2.0 Survivor Wants
It will be interesting to see if this one takes off more than a similar one that launched about a decade ago now...

http://techcrunch.com/2007/11/15/social-networking-platform-...

CrowdVine also let people setup custom white-label social networks, though I suppose its founder didn't have as neat of a background story as a Ning founder.

It's probably a nice business model, but not a "startup" by PG's standards, since this type of thing doesn't grow rapidly, intentionally.

windlep··on Why America abandoned nuclear power, and what we can learn from South Korea
If we ignore waste for a minute, this article highlights a key issue for why nuclear in the USA will never be as cheap as France or South Korea. Those countries can impose a single builder, single supplier requirement and enforce it the whole way through. That'd never happen here, everyone would have to get involved. Blame cronyism and the US lobbyist political system, but every nuclear company would freak out if they weren't the chosen provider, and then they'd sue.... and then it'd be as expensive as it is now.
windlep··on Ask HN: Is Python dying?
Yes, that was a bit of snark, sorry. Was hoping that would emphasize how huge of news it is that Python moved past PHP even on such an arbitrary language benchmark.
windlep··on Ask HN: Is Python dying?
Amongst what bubble of people you're entangled with?

I consider this a troll question because frequently I see HN questions like this completely disconnected from programming communities at large (which do not participate in HN), extrapolated to the wider web of all programmers. By this factor alone I'd expect Java to be completely obsolete by now.... but obviously no one is oblivious enough to reality to suggest that.

As for that question, if you want to build webapps right now, then yes, Python, as well as Ruby, and PHP, would be absolutely fantastic choices. The library ecosystems for all three of these are incredibly rich, mature, and well supported. Choose the language of these 3 that appeals to you the most, you will not be disappointed. I'm not going to tell you which one to choose, I think you'll be happy with whichever of these 3 languages appeals to you the most.

If you don't mind filling in the occasional gap, and like the bleeding edge of newness, try Rust, or Go. I've done both, they're fun languages with interesting paradigms (built-in lightweight threads vs. memory-safety at all costs FIGHT!).

Getting less attention? According to what? Did you see the the link about dominating science? Attention according to what group of people?

windlep··on Ask HN: Is Python dying?
Yes, Python is dying, that's why it just moved up in the Tiobe rankings to #5, displacing PHP (which obviously no one ever uses): http://www.tiobe.com/index.php/content/paperinfo/tpci/index....

It's dominance of science is why Python has 25% science talks this year at PyCon, and why we see articles like: http://www.infoworld.com/article/3012442/application-develop...

But yes, if you didn't know any languages, then of course you should invest in an immature language with no mature libraries for the tasks you need to complete, because you were given a few months of extra runway time by your boss to fill-in the library ecosystem instead of getting your job done. We'll ignore that PyPy places you damn close to Go in terms of performance (except with mature proven libs), and that usually your task won't be CPU-bound anyways (the GIL release on I/O tasks)....

Why do troll questions like this even hit the front page of HN?

windlep··on Firefox Can Now Get Push Notifications from Your Favorite Sites
A great example was given at the Chrome dev summit, which I think highlights the utility.

First, remember that you only need to click 'Yes' when your browser asks you for Push permission. You have revealed nothing new to the website, but provided it a way to contact you later. Think of it as a frictionless temporary e-mail.

So you go to a ticket website, or maybe its even a restaurant website, and there's some event coming up. Huh, yea, you want to know when tickets go on sale or whatever, but no way you want to give out your e-mail address again and get all that spam.

You instead opt for a push notification from the site when the tickets go on sale. Now you will be notified via your browser, and maybe once you see that notification, you're happy, you're done, so you unsubscribe (an option you can click on the notification itself to stop further push messages from that website).

If this privilege is abused, just as easy to cut-off that sole way to communicate that it has with you, right there on the notification. Unlike e-mail, when you kill the Push permission for a site, it has truly lost the ability to bug you ever again.

I'm sure there's plenty of other cases where it might be useful to one-off contact a user when they want to know about something your website provides, and people are (properly) wary about giving out e-mail addresses.

windlep··on Firefox Can Now Get Push Notifications from Your Favorite Sites
Unfortunately you can click on the notification in Firefox and immediately kill all further notifications from the spammers. Hopefully other implementations will be more friendly to spammers and hide the 'make it stop' button deep in a sub-sub menu under an elusive Settings app.
windlep··on Firefox Can Now Get Push Notifications from Your Favorite Sites
Firefox implements a quota system that restricts how many notifications may be sent "without user interaction". This is to reduce the likelihood that one could use this effectively for background tracking and to ensure you won't be swarmed with a gazillion of them if an application server has some bugs on sending notifications.

Bugzilla ticket: https://bugzilla.mozilla.org/show_bug.cgi?id=1153504

windlep··on Viskell: Visual programming meets Haskell
This is cool, but not really the problem I have, nor many I've talked to have when actually doing something 'real' in Haskell. (Granted we're a rare breed, actually trying to use Haskell for real-world use outside academia)

Show me how much memory a program will actually use. If it uses a lot, show me why it did, and where it did.

This is a solved problem for most mature languages, and the lack of tooling making it even remotely possible to figure this out in Haskell speaks volumes about how ready it is for "real world use".

windlep··on Usenet, what have you become? (2012)
In the past 3 years on usenet, something has changed though. Perhaps in response to this article and/or the others talking about it.

Some studios are getting drastically faster at getting their content pulled within minutes of nzb's appearing on the index sites. It's not as if its difficult to scan the groups and topics and issue take-down's on posts to the NSP's.

windlep··on Desperate not to have children
There is a massive cultural pressure on women in America (and in many countries) to have children. Its in the movies, magazines, and comes up amazingly often in casual conversations. Regardless of what people say, it also comes with a social stigma in different cases.

The point of this type of attention is to highlight the validity of making this choice in the hope that it might reduce the cultural pressure. I'm sure many men don't care, since the pressure is generally placed on women.

windlep··on The arms race for anti-drone weaponry
It seems people aren't thrilled with the prospect of debris landing on people underneath. More likely we'll end up with bigger drones that grab smaller drones with a net so they won't fall at this rate, or some sort of net-gun that after wrapping the drone immediately yanks it back fast enough that it won't hit the ground/people.
windlep··on A lot of websockets in Haskell
I have two samples of a websocket echo program in Haskell, and was unfortunately unable to make it not leak memory merely sending the same data back over the connections repeatedly. I will admit I haven't tested this lately, and I didn't use Network.Websocket because of this: https://github.com/jaspervdj/websockets/issues/72

Haskell code with tester is here: https://github.com/bbangert/ssl-ram-testing/tree/master/Hask...

(In some cases it would take some client churn to get the leak to occur, but clients come/go, a server has to survive this basic fact)

One diagnosis was that it was a memory fragmentation leak, since sure enough when I ran some debugging it reported fragmentation losses at the end. Some tweaks to the initial stack size and how much stack each increment should be done remedied it for the most part, but resulted in it taking quite a bit more memory (I believe I had to set the initial stack to at least 4k).

Using -N4 or -N6 (to turn on multi-core/cpu use in haskell) increased memory consumption quite a bit, as Haskell will now start juggling all those threads across real OS threads with its M:N scheduler (Just like Go has to do with its goroutines). It was drastically more memory efficient with -N1, even though that loses the multi-core utilization.

So far the most efficient implementation I've tested is of course... in C. Where a simple websocket echo used 9.5kb of memory per connection (including SSL, and with TCP kernel buffers set to 4k send/recv). I'm not really eager to write C code though, so we're using Python+twisted where a plain WS connection will take about 16kb per conn, or 23kb with SSL.

In this article's test, the kernel buffer for TCP send/recv was set to 1k, which I guess is fine if your payload will frequently be under that. But if you regularly are sending payloads exceeding that, the amount of wakes to keep shoveling data into the kernel buffer is going to be rather expensive.

As the Phoenix people note, its useful to keep in mind what you need to do, rather than merely how many connections you want to hold open.

windlep··on From Python to Go and Back Again
We're using twisted, but I believe Python 3's asyncio has a similar feature with use of non-blocking sockets, which is that you can add a hook to be triggered when too much data accumulates in user-space (can't be flushed to the kernel's tcp buffer).

In our case, when notifications buffer for a slow client, this API gets triggered and we mark the client connection as 'paused'. Until that state is cleared by more data getting to the client, notifications go to the database instead with just a flag on the client connection to check the db when the pending data was retrieved.

We do a similar thing on the receiving end to pause reading off the socket if we're already doing more work on behalf of the client at once than desired.

twisted documents this as producer/consumer: http://twisted.readthedocs.org/en/twisted-15.4.0/core/howto/...

windlep··on From Python to Go and Back Again
Nope, so, the goal here is to reduce how many machines (each with their own RAM limits) are used. The task is holding open bidirectional SSL wrapped long-lived websocket connections. They're held open for hours at a time, since we need to send notifications when we get them.

Every connection has a base cost of the TCP kernel send/recv buffer, which in our case we dropped a bit to 4kb each. So that's still 8kb per connection right there. If we terminate the SSL on a separate machine from where we handle the connection, then it means we'll be using 8kb more memory per connection. Probably even greater because nginx has its own send/recv buffers for data.

I'm sure our use-case is a unique one, most people care about raw through-put so the majority of SSL optimization has focused on lowering CPU use under high load rather than memory use under massive amounts of connections.

windlep··on From Python to Go and Back Again
Yep, this is what I meant by 'goroutine pools'. The select statements were on the sending side to ensure if the feed channel was full we wouldn't retain too much additional state. It works, but at that point its starting to look like an async event-loop with a thread-pool....
windlep··on From Python to Go and Back Again
We used Python 2.7 for pypy compatibility. I really dig the new async/await primitives added to Python 3.5 and think the asyncio path is the best path forward. I hope the work to get all the latest asyncio stuff working on PyPy picks up some steam.
windlep··on From Python to Go and Back Again
Regardless of how good you are, its easier to write code that has a predictable runtime memory footprint if you can actually predict how things will behave. Predicting an M:N scheduler is.... not easy.

This is part of why Rust removed the M:N scheduler and light-weight threads before Rust 1.0. It's hard to predict your memory use if the run-time is going to be creating/destroying OS threads, and juggling your lightweight threads (goroutines/etc) between real OS threads.

I agree entirely that the next iteration you write to solve the same problem is going to be better than the one before. The problem-scope is well defined, and you're already familiar with it and where the prior implementation was lacking. In this case the extra predictability of knowing what was going to be occurring at once did help.

windlep··on From Python to Go and Back Again
Why would it? Using twisted (or py3's asyncio), the event loop is spinning, there is no thread for Python to be switching to. Except that we're using a thread-pool of course (to make external blocking network calls), and those threads are.... making network requests, which is I/O, and the GIL releases during that.

On a network bound daemon, which is not CPU-bound, the GIL is really not an issue, so it never came up.

windlep··on From Python to Go and Back Again
I have to note this, because I think it deserves quite a bit more attention.

SSL is extremely expensive, on RAM (perhaps the implementations have optimized for throughput over RAM). I have yet to benchmark any SSL implementation in any language, with any binding, that can use less than 20kb per SSL connection. I mentioned in my talk here that SSL is very expensive, here's my benchmark suite that others may add to: https://github.com/bbangert/ssl-ram-testing/

I have implementations in several languages, so far both Go and Python 3.4 can get as low as the 20kb cited. If you can get your per-connection state below 20kb, then merely adding SSL means doubling or worse your RAM requirements, which is huge.

I appreciate that everyone loves obsessing on the language wars, but the SSL RAM overhead affects us regardless of language. I covered that in one of the slides near the end, it'd be great to see some movement on reducing the RAM footprint here.

windlep··on From Python to Go and Back Again
So do I! Eventually you 'top-out' in a language/framework though... and then its all tears.
windlep··on From Python to Go and Back Again
I should note, we don't care about throughput for the most part. Our constraint is purely the memory use of holding open the connections. The aim is to hold as many connections as possible within 10-20% of the machines RAM, and not exceed it. As such, we need to be careful about resource usage and spikes.

Goroutines feel cheap, but if you're holding 140k connections, and just 20k of them do something that spins up a goroutine each... you can easily exceed the memory constraint. As such, we had to put goroutine pools in place, careful select statements around them from connections to ensure we didn't overwhelm external resources, etc. It was a huge pain. It has been drastically easier to control resource usage with these constraints under python/twisted.

YMMV, of course, this is just our experience. Part of the reason for putting it out there is that there are already many people who have talked/blogged about going from Python -> Go. I thought maybe the world could handle just one story about going the other direction.

windlep··on From Python to Go and Back Again
This was before Go 1.4, which dropped memory use per goroutine from 8kb -> 2kb. They're fairly close now (minus my leaking goroutines). ;)
windlep··on From Python to Go and Back Again
It could've been. Though now that so much of heka is involved in moving data between the Lua layer, turning it into plain C is a better option. trink, one of the heka authors has a project called hindsight that does just that.
windlep··on From Python to Go and Back Again
I mentioned during the talk, that the reason for giving it a spin in Python in the first place was that we had to fill in gaps in a Go library. While there's lots of Go libraries, many of them are immature, and have chunks of functionality missing.

So while I was blocked on a coworker filling in one of the gaps we both needed, I was able to rewrite it all in Python.

I'll probably give this talk again at a venue where it'll be recorded, which should add a lot of missing context to these slides.

windlep··on From Python to Go and Back Again
I meant that partly as a joke, I do happen to like Rust though. And in the context of this technical problem, its memory control would make it an attractive possibility (as would C/C++/etc). Lots of context missing as these are merely slides, and I said quite a bit more than what is presented here.
windlep··on From Python to Go and Back Again
For heka, one of the things we wanted besides performance, was a small, easy-to-distribute binary you could drop on a system and 'just run'. Go is fantastic for distribution thanks to the small staticly linked binaries you can get out of it. To accommodate the pluggable filters and such later, a Lua sandbox system was added... and oddly some of the other Go pieces ended up being faster in Lua which is why Lua decoders/inputs are now an option for heka as well.

Note: I gave this talk.

← PreviousPage 4 of 6Next →