HNHacker News
TopNewBestAskShowJobs

rtomayko

1,022 karma · joined October 26, 2008

submissionscomments
rtomayko··on Homebrew — MacPorts driving you to drink? Try Homebrew
Yep. It's not bad. I cloned the [experimental git repository](http://ftp.netbsd.org/pub/NetBSD/misc/repositories/git/pkgsr...) to `/usr/pkgsrc` and was able to install most packages I tried. They seem to lag behind current versions quite a bit and some pieces of software I rely on for work weren't packaged (redis, mongo, etc.).

I used it for a few months but eventually switched over to homebrew because it's a nice simple system and packages most of the stuff I need.

You have to run a case-insensitive filesystem with pkgsrc (I was anyway) and, like macports, it does not use system libraries so pretty much everything needs to be rebuilt under `/usr/pkg`.

It was worth experimenting with. I might check back on it when I get my new MBP. They have [a lot of packages](http://pkgsrc.se/).

rtomayko··on Extreme agility (with more on GitHub process by rtomayko)
Also, I personally wouldn't call what we do "extreme agility" (whatever that means). "Flexible", "minimal process", "ad hoc" are all more accurate (and less gut wrenching) ways of describing it if you ask me.
rtomayko··on What Pythonistas Think of Ruby
You can pass an anonymous function or lambda:

    def foo(thing, block):
      thing = "cruel " + thing
      block(thing) # like `yield thing' or 'block.call' in ruby

    def bar(thing):
      return "hello " + thing

    foo('world', bar)

    # or:
    foo('world', lambda x: "hello " + x)
Ruby's blocks are really just sugar for passing an anonymous function in the last argument and yield is just sugar for calling that function. The example above in Ruby would be:

    def foo(thing)
      yield thing
    end

    foo('world') { |thing| "hello " + thing }
rtomayko··on What Pythonistas Think of Ruby
Yep. `yield` in Ruby is a normal anonymous method call. It pushes a new frame onto the stack. `yield` in Python works more like Ruby's [Generator](http://ruby-doc.org/stdlib/libdoc/generator/rdoc/classes/Gen...). It freezes the current stack frame's state and resumes execution somewhere else, returning again to the same place on the next iteration. They're very different things really.

More about Python's generators here:

http://www.python.org/dev/peps/pep-0255/

rtomayko··on Protecting your email with 'AT domain DOT com' is making it easier to find
I recommend "me MONKEY TAIL domain FULL STOP com".

More: <http://ascii-table.com/pronunciation-guide.php>;

rtomayko··on Ron : Humane text format and toolchain for creating UNIX man pages
Me too, actually. I tried to keep Ron 100% markdown compatible but broke that with the `<VAR>` syntax. It'll probably break with Markdown more in the future, as I can already see places (pre-formatted blocks) where I'm going to want slightly different behavior.

One of the best defenses against documentation rot is a free, ultra simple, and portable toolchain. I'd like Ron to eventually be entirely in C (based on Discount, most likely) with very few dependancies, if any. If the format turns out to be useful, I'll start moving in that direction.

rtomayko··on GitHub's Unicorn Setup
> Actually, antonovka did an excellent job explaining it above. The most important aspect is that threads are "lighter weight" than processes. They use less memory and are quicker to context switch (usually).

Processes and threads have very similar execution models under most Unixes from what I understand. Threads don't use all that much less memory, either, given a copy-on-write friendly environment (e.g., not Ruby MRI). Perhaps you're confusing threads vs. processes under Windows or Java to threads vs. processes under Unix?

> The result of this lighter weight is that you can spawn more threads than you could processes, on the same hardware. And when you're using one thread/process per connection, that means more concurrent connections on the same hardware. So, if Unicorn used its exact same architecture, but replaced the worker processes with worker threads, you could scale much better.

You're crazy. If Unicorn were 1.) somehow able to take advantage of native threads (it's not), and 2.) moved to a thread-per-connection model instead of a process-per-connection model, it would have basically zero practical impact on the efficiency with which it processes requests. It's already sharing a great deal of its base memory footprint thanks to preloading in the master and fork, so processes don't have significant memory overhead. It's using the kernel to balance requests between processes, so it's not like there's a bunch of IPC between master and worker processes that could be removed with threads.

Say you're running 8 process-per-connection backends on eight cores and each process is 100% CPU bound processing requests. You have a load of 8.0, machine is 100% utilized. If you then change this to a single process with 8 native-thread-per-connection workers, absolutely nothing will change. The load will still be 8.0. You can start more threads to do work but it will have the near exact same effect as starting the same number of processes.

Process-per-connection doesn't fall down under these levels of concurrency. It does eventually - you can't use process-per-connection to solve C10K problems, for instance. But we're talking about Ruby backends, which are always managed as multiple processes due purely to the way Ruby web apps are written (not efficient, not async). Requests execute within a giant request-sized Mutex lock.

And even if threads were considerably more efficient than processes, you still don't want to run a lot of them because each consumes network resources, like database/memcached connections. Using native threads would not let Rails apps spawn thousands (or even hundreds) of thread-per-connection workers. A high concurrency threading model works for Apache (and Varnish and Squid) because the work performed in each thread is fairly simple and doesn't require the kind of network interaction and resource use that an app backend does.

Basically, this notion that threads (even native threads) would be a considerable improvement to Unicorn's design is just all wrong.

> Secondly, haproxy is written in C, which generally means it's going to perform much better and use a lot less memory than a Ruby webserver. This translates, once again, to more output from the same amount of hardware.

Your world seems considerably more simplistic than mine. I'm not even sure how haproxy and unicorn can be compared in any useful way. Unicorn is not a proxy. The master process does not do userland TCP balancing or anything like that. Unicorn is designed to run and manage single-threaded Ruby backends efficiency, HAproxy is a goddam high availability TCP proxy.

> That's why I was pretty surprised to see that github would choose both Ruby and pre-fork over C and threads (or in the case of haproxy, async, which scales even better).

I think you're confusing the types of constraints you have when you're building high concurrency, special purpose web servers and intermediaries (like nginx and haproxy) with the types of constraints you have when you're building a container for executing logic-heavy requests in an interpreted language. Nginx and HAproxy have excellent designs for what they do, and so does Unicorn. They're different because they do different things.

rtomayko··on Things Caches Do
Me too :)
rtomayko··on Advanced Squid Caching for Rails Applications: Preface
Ahhh, I see. Like telling a joke in the first person because it just works better.

Well, that's definitely good to know. It does read as if you were forced to discover the concept independently, though, which might be a tad confusing for those familiar with the technique. Maybe it's just me.

At any rate, I do like the clear description of the situation and discussion that led to putting a gateway cache in place. It helps make things click.

rtomayko··on Advanced Squid Caching for Rails Applications: Preface
I'd say only positively.

Regarding the article, this statement really freaked me out:

> So, we’ve got an idea - why can’t we place such a server in front of our application and make it cache content for all users in the world?

Seriously? They'd never even _heard_ of gateway / reverse proxy caching? They came up with it independently? I knew HTTP caching wasn't understood very well but this shows that it's so much worse than I imagined.

It's sad that such a fundamental aspect of the web's architecture is just completely off the radar for so many "web developers". That's not a knock on the Scribd folks, it's a systemic problem across our entire industry as far as I can tell.

← PreviousPage 3 of 3