<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-3187374</id><updated>2008-05-11T10:41:35.676-07:00</updated><title type='text'>saladwithsteve</title><link rel='alternate' type='text/html' href='http://saladwithsteve.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default?start-index=26&amp;max-results=25'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>759</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3187374.post-2679085493260527358</id><published>2008-05-11T10:32:00.000-07:00</published><updated>2008-05-11T10:41:35.891-07:00</updated><title type='text'>John McCarthy has a good sense of humor</title><content type='html'>From an informal talk he gave at Stanford recently that was written up in &lt;a href="http://news.ycombinator.com/item?id=185348"&gt;Hacker News&lt;/a&gt;:

&lt;blockquote&gt;
&lt;pre&gt;
Q. Can computers know?

A. This is largely a question of definition. If a camera looked at a table, we could
say it "knows" that there are four containers of liquid on the table (which was true).

Q. Is there any definition of "know" in which computers cannot succeed?

A. Well, I suppose the biblical sense.

Q. Ha, well, what makes you think that?

A. They don't satisfy the necessary axioms (laughter)
&lt;/pre&gt;
&lt;/blockquote&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2008/05/john-mccarthy-has-good-sense-of-humor.html' title='John McCarthy has a good sense of humor'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=2679085493260527358' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/2679085493260527358'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/2679085493260527358'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-6377490104933287377</id><published>2008-04-21T20:08:00.000-07:00</published><updated>2008-04-21T20:12:44.217-07:00</updated><title type='text'>What are you doing?</title><content type='html'>reading @&lt;a href="http://blog.twitter.com/2008/04/welcome-john-and-steve.html"&gt;biz&lt;/a&gt; out me as a Twitter employee.</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2008/04/what-are-you-doing.html' title='What are you doing?'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=6377490104933287377' title='6 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/6377490104933287377'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/6377490104933287377'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-5210323149609574287</id><published>2008-04-15T09:36:00.000-07:00</published><updated>2008-04-20T08:19:37.714-07:00</updated><title type='text'>curious what delicious is saying about something?</title><content type='html'>&lt;a href="javascript:location.href='http://del.icio.us/url/check?&amp;url='+encodeURIComponent(location.href)"&gt;Here's a bookmarklet that checks the current URL you're visiting with del.icio.us&lt;/a&gt;.</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2008/04/curious-what-delicious-is-saying-about.html' title='curious what delicious is saying about something?'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=5210323149609574287' title='3 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/5210323149609574287'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/5210323149609574287'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-4527552100593290558</id><published>2008-04-13T11:41:00.000-07:00</published><updated>2008-04-13T11:52:19.500-07:00</updated><title type='text'>My first Thrift app</title><content type='html'>&lt;p&gt;
When you find yourself working on big systems, a useful technique is
to decompose it into services. Moving from a big monolithic server to
a bunch of separate services can be a big challenge but if you had
foresight, many of your services were already decoupled in your system
from day 1 even though you were deploying it monolithicly.
&lt;/p&gt;
&lt;p&gt;
A common technique for decomposing services is using RPC. At Google, we
used protocol buffers, which were briefly descibed in the &lt;a href="http://labs.google.com/papers/sawzall-sciprog.pdf"&gt;Sawzall&lt;/a&gt;
paper.
&lt;/p&gt;
&lt;p&gt;
Basically, you describe your data and the interface that process the
data in a language-independent format (a DDL, essentially) and use code
generators to turn that DDL into set of objects in your target
langauge that can create and send those structures over the wire. This
makes it easy to write servers in one language and clients in another
and the generated code deals with serialization.
&lt;/p&gt;
&lt;p&gt;
I found that using a DDL to describe your code and services was really
nice. When building a new service, you could simply reference your DDL
in the design doc and have a meanginful discussion about the service
without getting into the details of how it would be written until you had
the semantics nailed down.
&lt;/p&gt;

&lt;p&gt;
Facebook, as they were growing, decided to move to a homegrown binary
RPC mechanism similar to protocol buffers called &lt;a href="http://developers.facebook.com/thrift/"&gt;Thrift&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
Let's say I wanted to write a simple service that would tell the
client what time it was on the server. Here would be the DDL file
describing both the data and the service plus a little extra to help
out the generated code files.
&lt;/p&gt;
&lt;pre name="code" class="thrift"&gt;
# time.thrift
namespace java tserver.gen
namespace ruby TServer.Gen

typedef i64 Timestamp

service TimeServer {
  // Simply returns the current time.
  Timestamp time()
}
&lt;/pre&gt;

&lt;p&gt;
After running &lt;tt&gt;thrift --gen java --gen rb time.thrift&lt;/tt&gt; on the
file, I'd have an interface and server that I could implement in Java
and a client that I could use in Ruby.
&lt;/p&gt;
&lt;p&gt;
Based on the generated java code, I could write a short server in Scala:
&lt;/p&gt;

&lt;pre name="code" class="scala"&gt;
&lt;code&gt;
package tserver

import tserver.gen._
import com.facebook.thrift.TException
import com.facebook.thrift.TProcessor
import com.facebook.thrift.TProcessorFactory
import com.facebook.thrift.protocol.TProtocol
import com.facebook.thrift.protocol.TProtocolFactory
import com.facebook.thrift.transport.TServerTransport
import com.facebook.thrift.transport.TServerSocket
import com.facebook.thrift.transport.TTransport
import com.facebook.thrift.transport.TTransportFactory
import com.facebook.thrift.transport.TTransportException
import com.facebook.thrift.server.TServer
import com.facebook.thrift.server.TThreadPoolServer
import com.facebook.thrift.protocol.TBinaryProtocol

/**
 * TimeServer.time returns the current time according to the server.
 */
class TimeServer extends TimeServer.Iface {
  override def time: Long = {
    val now = System.currentTimeMillis
    println("somebody just asked me what time it is: " + now)
    now
  }
}

object SimpleServer extends Application {
  try {
    val serverTransport = new TServerSocket(7911)
    val processor = new TimeServer.Processor(new TimeServer())
    val protFactory = new TBinaryProtocol.Factory(true, true)
    val server = new TThreadPoolServer(processor, serverTransport,
      protFactory)
    
    println("starting server")
    server.serve();     
  } catch { 
    case x: Exception =&amp;gt; x.printStackTrace();
  }
}
&lt;/code&gt;
&lt;/pre&gt;

&lt;p&gt;
(Geez, most of that space was taken up in my obsessive need to separate
out all my imports. You can thank Google for that bit of OCD.)
&lt;/p&gt;
&lt;p&gt;
The client is even shorter:
&lt;/p&gt;
&lt;pre name="code" class="ruby"&gt;
&lt;code&gt;
#!/usr/bin/ruby
$:.push('~/thrift/lib/rb/lib')
$:.push('../gen-rb')

require 'thrift/transport/tsocket'
require 'thrift/protocol/tbinaryprotocol'
require 'TimeServer'

transport = TBufferedTransport.new(TSocket.new("localhost", 7911))
protocol = TBinaryProtocol.new(transport)
client = TimeServer::Client.new(protocol)

transport.open()

puts "I wonder what time it is. Let's ask!"
puts client.time()
&lt;/code&gt;
&lt;/pre&gt;
&lt;p&gt;
The ruby client took about 20ms to get an answer from the Scala server.
&lt;/p&gt;
&lt;p&gt;
Thrift advantages:&lt;br /&gt;
&lt;ul&gt;
  &lt;li&gt;Pipelined connections means you spend less time in connection setup/teardown and TCP likes longer-lived connections.&lt;/li&gt;
  &lt;li&gt;Asynchronous requests. Asynchronous replies would be nice too but would be trickier to use.&lt;/li&gt;
  &lt;li&gt;Binary representation is much more efficient to transmit and process than, say, XML.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
Thrift drawbacks: &lt;br /&gt;
&lt;ul&gt;
  &lt;li&gt;Integrating generated source into your build system can be tricky. 
      Typically, you rarely have to regenerate your stubs but debugging generated code can be a huge pain.&lt;/li&gt;
  &lt;li&gt;It's Java server should move away from ServerSocket to NIO for increased throughput. 
      That's probably not more than a week's work as long as the existing code isn't too tightly coupled.&lt;/li&gt;
  &lt;li&gt;Currently it doesn't build cleanly on the Mac. I did some work and got it working but I don't think it's used
      extensively on the Mac so if that's your primary platform, you should be prepared to send them patches from time to time.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;
If you're looking to move towards decoupled services, Thrift is worth a hard look.
&lt;/p&gt;
&lt;p&gt;
Here's a tarball with my &lt;a href="http://saladwithsteve.com//code/timeserver.tar.gz"&gt;time
server&lt;/a&gt;. It contains all the generated code as well as
libthrift.jar and a Makefile to run the example server.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2008/04/my-first-thrift-app.html' title='My first Thrift app'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=4527552100593290558' title='3 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/4527552100593290558'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/4527552100593290558'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-444274540799770784</id><published>2008-04-06T18:25:00.000-07:00</published><updated>2008-04-06T18:53:08.429-07:00</updated><title type='text'>GVN and gold</title><content type='html'>&lt;p&gt;
Two things popped up on my radar recently:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://code.google.com/p/gvn/"&gt;gvn&lt;/a&gt;, Google's wrappers around Subversion to help them work in their code-review heavy workflow. Even if you're not into code reviews, &lt;code&gt;tkdiff&lt;/code&gt; integration is a nice improvement over &lt;code&gt;colordiff&lt;/code&gt; or &lt;code&gt;FileMerge&lt;/code&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.airs.com/blog/archives/164"&gt;gold&lt;/a&gt;, a new ELF linker built with giant binaries in mind. When you're building 900MB+ static binaries routinely, linking speed matters. gold claims to be at least 5x faster currently. Even if you have a massive distcc cluster, linking is still serial. One of gold's future design goals is to be concurrent and that would be pretty awesome. Imagine how fast I could link with a concurrent linker on my 8-core Mac Pro! Not that using an ELF linker under Leopard helps much since OS X uses Mach-O binaries but hey, there's always cross-compiling.
&lt;/p&gt;
&lt;p&gt;
BTW, Ian Lance Taylor, the author of gold, has &lt;a href="http://www.airs.com/blog/archives/38"&gt;an excellent series of blog articles on linkers.&lt;/a&gt;
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2008/04/gvn-and-gold.html' title='GVN and gold'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=444274540799770784' title='2 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/444274540799770784'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/444274540799770784'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-6855696975621938799</id><published>2008-03-14T09:45:00.000-07:00</published><updated>2008-03-14T09:51:06.166-07:00</updated><title type='text'>It's not just you</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://saladwithsteve.com/uploaded_images/down-791122.png"&gt;&lt;img alt="[downorjustyou]" style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://saladwithsteve.com/uploaded_images/down-791087.png" border="0" alt="" /&gt;&lt;/a&gt;

Since it's back now, check out &lt;a href="http://downforeveryoneorjustme.com/"&gt;al3x's neat new site&lt;/a&gt;.</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2008/03/its-not-just-you.html' title='It&apos;s not just you'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=6855696975621938799' title='2 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/6855696975621938799'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/6855696975621938799'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-8257988765334743789</id><published>2008-03-01T21:20:00.000-08:00</published><updated>2008-03-01T21:58:51.426-08:00</updated><title type='text'>White People think Indian Food is Hot.</title><content type='html'>I just finished reading a &lt;a href="http://www.amazon.com/Buddha-Penguin-Lives-Karen-Armstrong/dp/0670891932"&gt;secular biography of the Buddha&lt;/a&gt; recently and Stacy and I were chatting about the Buddha's magic &lt;a href="http://en.wikipedia.org/wiki/Iddhi"&gt;Iddhi&lt;/a&gt; powers which he acquired as a highly skilled yogin. She said her first impressions of yoga came from watching Dhalsim's stretchy limbs in Street Fighter II. As a kid, she figured there must be some small kernel of truth to that. Equally stupid is that, as a kid, that's exactly where I got my first impressions of Indian food from. The manual says that Dhalsim got his "Yoga Flame" from the hot curry he ate.

&lt;object width="425" height="355"&gt;&lt;param name="movie" value="http://www.youtube.com/v/c6Y7HjZCRfo"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/c6Y7HjZCRfo" type="application/x-shockwave-flash" wmode="transparent" width="425" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;

I couldn't imagine a food so hot that you felt like you were breathing fire. Wasn't that a bad meal? Wouldn't you ask for your money back? How could a place like that stay in business? These types of comics didn't help, either:
&lt;p&gt;
&lt;a href="http://www.cartoonstock.com/directory/h/hot_foods_gifts.asp"/&gt;&lt;img src="http://www.cartoonstock.com/newscartoons/cartoonists/mfl/lowres/mfln343l.jpg"/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
This clichéd comedic target was common in the magazines that adults read when I was a kid, the particular one I've always remembered had a guy running to the bathroom with flames coming out of his pants in a restaurant with a clearly Indian name. At 10, I recognized the dangers that the comic bravely warned me of. I knew that often political comics took aim at targets that the media didn't dare attack and figured this must be the same.
&lt;/p&gt;
&lt;p&gt;
The first time somebody actually offered me Indian food, I was very nervous. It had a dangerously bright orange color but smelled and tasted great. Thankfully fire did not come out of my ass and set my pants on fire.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2008/03/white-people-think-indian-food-is-hot.html' title='White People think Indian Food is Hot.'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=8257988765334743789' title='2 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/8257988765334743789'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/8257988765334743789'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-4668932024792123408</id><published>2008-02-17T09:58:00.000-08:00</published><updated>2008-02-17T10:47:26.004-08:00</updated><title type='text'>JavaScript undefined vs. null</title><content type='html'>&lt;p&gt;
I was reading a modern, popular book on JavaScript last night and was disappointed by the handling of null. The author started out doing a lot of checking like:
&lt;/p&gt;
&lt;code&gt;
if (foo == null) {
&amp;nbsp;&amp;nbsp;alert('foo is not set.');
}
&lt;/code&gt;
&lt;p&gt;
Then told the reader that they could just remove the &lt;code&gt;== null&lt;/code&gt; because javascript knows you mean &lt;code&gt;"== null"&lt;/code&gt;
&lt;/p&gt;
&lt;p&gt;
What?! This isn't why you don't check for equality with null. It's because &lt;code&gt;foo == null&lt;/code&gt; doesn't even remotely do what most people think it does in this context.
&lt;/p&gt;
&lt;p&gt;
It's a commonly held belief that uninitialized properties in JavaScript are set to &lt;code&gt;null&lt;/code&gt; as default values. People believe this mostly for 2 reasons: 1) &lt;code&gt;foo == null&lt;/code&gt; returns true if foo is undefined and 2) authors don't teach JavaScript properly.
&lt;/p&gt;
&lt;p&gt;
A property, when it has no definition, is undefined. Put that way, it's pretty obvious.
&lt;/p&gt;
&lt;p&gt;
&lt;code&gt;null&lt;/code&gt; is an object. It's type is &lt;code&gt;null&lt;/code&gt;. &lt;code&gt;undefined&lt;/code&gt; is not an object, it's type is &lt;code&gt;undefined&lt;/code&gt;. That part is less obvious.
&lt;/p&gt;
&lt;p&gt;
The real trouble is that &lt;code&gt;==&lt;/code&gt; does type coercion. &lt;code&gt;===&lt;/code&gt; checks for both type and value and is the most intuitive form of equality in JavaScript, in my opinion.
&lt;/p&gt;
&lt;p&gt;
I fired up a &lt;a href="http://www.billyreisinger.com/jash/"&gt;Jash&lt;/a&gt; console to hopefully clear things up for you.
&lt;/p&gt;
&lt;p&gt;
&lt;pre&gt;
&amp;gt;&amp;gt; window.hello
null
&amp;gt;&amp;gt; window.hello.something
window.hello has no properties
&amp;gt;&amp;gt; window.hello == null
true
&amp;gt;&amp;gt; window.hello === null
false
&amp;gt;&amp;gt; window.hello === undefined
true
&amp;gt;&amp;gt; if (window.hello) { alert('truthy'); } else { alert('falsy'); } // will print falsy.
null
&amp;gt;&amp;gt; window.hello == undefined
true
&amp;gt;&amp;gt; null == undefined
true // there's the rub, sir.
&amp;gt;&amp;gt; null
null
&amp;gt;&amp;gt; undefined
null
&amp;gt;&amp;gt; typeof null
object
&amp;gt;&amp;gt; typeof undefined
undefined
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
So people write
&lt;pre&gt;
if (foo == null) {
&amp;nbsp;&amp;nbsp; foo = "Joe";
}
&lt;/pre&gt;

When what they really mean is
&lt;pre&gt;
if (!foo) {
&amp;nbsp;&amp;nbsp; foo = "Joe";
}
&lt;/pre&gt;

If you find yourself with a lot of &lt;code&gt;null&lt;/code&gt; checks in your JavaScript, set aside some time and watch Douglas Crockford's &lt;a href="http://video.yahoo.com/watch/111593"&gt;"The JavaScript Programming Language"&lt;/a&gt; talk on Yahoo Video. It's part 1 of a 3-part series of excellent and enlightening talks.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2008/02/javascript-undefined-vs-null.html' title='JavaScript undefined vs. null'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=4668932024792123408' title='6 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/4668932024792123408'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/4668932024792123408'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-7025017327244635511</id><published>2008-02-10T20:55:00.000-08:00</published><updated>2008-02-10T21:08:22.664-08:00</updated><title type='text'>Ubuntu on the Mac Pro</title><content type='html'>&lt;p&gt;
Last year I bought a Mac Pro to replace my aging Linux PC. It was a pretty significant upgrade, from a HyperThreaded 2.5Ghz Pentium 4 to a dual-processor, quad-core 3Ghz Xeon with 8G of RAM. Leopard is nice but I wanted to try and get Ubuntu running on it.
&lt;/p&gt;
&lt;p&gt;
Here's the setup, I have 4 drives:
&lt;ul&gt;
&lt;li&gt;750G - Leopard&lt;/li&gt;
&lt;li&gt;200G - Windows&lt;/li&gt;
&lt;li&gt;750G - Backups&lt;/li&gt;
&lt;li&gt;750G - To be Ubuntu&lt;/li&gt;
&lt;/ul&gt;
and wanted to install Ubuntu on the 4th drive.
&lt;/p&gt;

&lt;p&gt;
Here are the basic steps I followed:
&lt;ol&gt;
&lt;li&gt; Install &lt;a href="http://refit.sourceforge.net/"&gt;refit&lt;/a&gt;&lt;/li&gt;
&lt;li&gt; Install from LiveCD (7.10)&lt;/li&gt;
&lt;li&gt; Select manual Manual Partition and from the advanced options, choose hd3,0. I setup my disk with one ext3 partition and 1 swap partition.&lt;/li&gt;
&lt;li&gt; After install, boot the linux disk from the refit menu&lt;/li&gt;
&lt;li&gt; Grub will get to stage 1.5, you will see the menu but be unable to start the system, it will complain about unknown partition type&lt;/li&gt;
&lt;li&gt; hit 'c'&lt;/li&gt;
&lt;/ol&gt;
&lt;/p&gt;
&lt;p&gt;
Here's a transcript of my tinkering with grub to find the right drive with my initrd and kernel on it so I could boot my fancy Apple-branded Linux machine.
&lt;/p&gt;
&lt;pre&gt;
grub&gt; root (hd&amp;lt;TAB&amp;gt;
&lt;/pre&gt;
showed a bunch of drives with various partitions but most importantly showed that hd0,0 had the Linux partition I was looking for. Even though with the ubuntu installer, we told it to use hd3, here we use hd0. the boot manager has shuffled the order of the drives. Telling the ubuntu installer to use hd0,0 will only result in an unbootable disk.
&lt;pre&gt;
grub&gt; root (hd0,0)
grub&gt; kernel /boot/vmlinuz&amp;lt;TAB&amp;gt;
&lt;/pre&gt;
will show you some vmlinuz files. typically just the one ubuntu installed. pick it.
&lt;pre&gt;
grub&gt; kernel /boot/vmlinuz-2.6.22-14-generic root=/dev/sdd1 ro
grub&gt; initrd /boot/initrd.img-2.6.22-14-generic
grub&gt; boot
&lt;/pre&gt;
&lt;p&gt;
Now your system will boot. Edit your /boot/grub/menu.lst to point the root (hd0,0)
&lt;/p&gt;
&lt;p&gt;
Now reboot and you will be in Ubuntu. Your wifi adapter won't work. &lt;a href="https://help.ubuntu.com/community/WifiDocs/Driver/bcm43xx/Feisty_No-Fluff#head-bc33832c0547766a33c3a84f13f971ca757b2851"&gt;Follow these steps to enable ndiswrapper to use the windows drivers.&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I used a usb thumb drive to move the windows drivers zip file between my laptop and desktop.
&lt;/p&gt;
&lt;p&gt;
Once you have networking up, don't forget to enable ssh so you can login in case you screw up your X config. 
&lt;/p&gt;
&lt;p&gt;
Edit /etc/apt/sources.list to include what you might want.
&lt;/p&gt;

&lt;p&gt;
I have an ATI Radeon X1950 Pro video card. To get it working, I simply installed &lt;a href="http://albertomilone.com/nvidia_scripts1.html"&gt;Envy&lt;/a&gt; which downloaded the right drivers and installed them for me. 
&lt;/p&gt;
&lt;p&gt;
But it didn't span monitors, they were just clones so I ran aticonfig (which &lt;a href="http://albertomilone.com/nvidia_scripts1.html"&gt;Envy&lt;/a&gt; installed for me)
&lt;pre&gt;
aticonfig --initial=dual-head --overlay-on=1
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;
And we were good to go.
&lt;/p&gt;

&lt;p&gt;
Banshee imported all my music from my iPod after converting it's database from an iTunes format it didn't recognize.
&lt;/p&gt;
&lt;p&gt;
Using hibernate left the Mac's wifi adapter in a weird state. Rebooting it didn't help but booting into OS X and back into Linux corrected the wifi card.
&lt;/p&gt;
&lt;p&gt;
The fan speed still isn't quite right, various fans will become louder and softer at odd intervals. I will try monkeying with lm-sensors later.
&lt;/p&gt;
&lt;p&gt;
I have nice smooth fonts by running Emacs 23 from &lt;a href="http://peadrop.com/blog/2007/01/06/pretty-emacs/"&gt;Alexandre Vassalotti&lt;/a&gt;'s repo and the &lt;a href="http://www.ghostscript.com/~raph/type/myfonts/inconsolata.html"&gt;Inconsolata&lt;/a&gt; font for programming.
&lt;/p&gt;
&lt;p&gt;
Overall, it's a great Linux machine and maybe one day it won't be so much trouble to get running. Hopefully my instructions will help you get it up and running. 
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2008/02/ubuntu-on-mac-pro.html' title='Ubuntu on the Mac Pro'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=7025017327244635511' title='2 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/7025017327244635511'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/7025017327244635511'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-6037078286459074825</id><published>2007-11-19T22:32:00.000-08:00</published><updated>2007-11-19T22:39:23.730-08:00</updated><title type='text'>Lift Tutorial</title><content type='html'>&lt;p&gt;
I've been working on &lt;a href="http://liftweb.net/"&gt;lift&lt;/a&gt; quite a bit lately, fitting it in with some other projects and my obsessive need for football. (Both NFL and Madden)
&lt;/p&gt;
&lt;p&gt;
If you're interested in trying it out, give the &lt;a href="http://liftweb.net/index.php/HowTo_start_a_new_liftwebapp"&gt;lift tutorial&lt;/a&gt; I wrote a try. Please &lt;a href="http://groups.google.com/group/liftweb"&gt;drop us a note&lt;/a&gt; if you have any problems.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/11/lift-tutorial.html' title='Lift Tutorial'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=6037078286459074825' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/6037078286459074825'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/6037078286459074825'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-4786591912309100020</id><published>2007-10-21T16:57:00.000-07:00</published><updated>2007-10-21T17:29:14.456-07:00</updated><title type='text'>Tomato Wifi!</title><content type='html'>&lt;p&gt;
While doing that podcast with Daniel, I noticed I was seeing 30% or so packet loss on my wifi network. After rebooting some equipment and keeping an eye on things, I decided to scrap my faulty Airport Express base stations and replace them with &lt;a href="http://www.linksys.com/servlet/Satellite?c=L_Product_C2&amp;childpagename=US%2FLayout&amp;cid=1133202177241&amp;pagename=Linksys%2FCommon%2FVisitorWrapper"&gt;Linksys WRT54GL&lt;/a&gt;s running a custom opensource firmware called &lt;a href="http://www.polarcloud.com/tomato"&gt;Tomato&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
While the instructions are good, they assume you already have the router up and running. The first thing I realized was to throw the windows install cd away and just plug my mac into the switch on the back. The router will be listening on &lt;a href="http://192.168.1.1"&gt;192.168.1.1:80&lt;/a&gt; with a username and password of admin/admin. &lt;a href="http://en.wikibooks.org/wiki/Tomato_Firmware"&gt;The instructions&lt;/a&gt; will carry you from that point.
&lt;/p&gt;
&lt;p&gt;
I have a 3 story house so I bought two routers and bridged them together with &lt;a href="http://en.wikipedia.org/wiki/Wireless_Distribution_System"&gt;WDS&lt;/a&gt;. My only complaint is that Tomato's WDS &lt;a href="http://www.polarcloud.com/tomatofaq#how_do_i_use_wds"&gt;is difficult to setup.&lt;/a&gt; The Airport Express admin utility did a wonderful job of easily bridging the two aiport express base stations together.
&lt;/p&gt;
&lt;p&gt;
Except for one of the routers dying after only a few days, which Amazon was nice enough to replace for free with next-day shipping, things have been great on Tomato. 4 bars everywhere I go in the house.
&lt;/p&gt;
&lt;small&gt;[Hat tip to &lt;a href="http://www.somebits.com/weblog/tech/good/tomato-firmware.html"&gt;Nelson for the recommendation.&lt;/a&gt;]&lt;/small&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/10/tomato-wifi.html' title='Tomato Wifi!'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=4786591912309100020' title='5 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/4786591912309100020'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/4786591912309100020'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-833032289943435889</id><published>2007-10-06T21:33:00.001-07:00</published><updated>2007-10-06T21:36:29.417-07:00</updated><title type='text'>My interview with Daniel Brusilovsky</title><content type='html'>Daniel runs the Apple Universe podcast and &lt;a href="http://appleuniverse.mypodcast.com/2007/10/Apple_Universe_Episode_61_Blogging_with_Blogger-46676.html"&gt;interviewed me today&lt;/a&gt;. We had a fun chat, check it out!</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/10/my-interview-with-daniel-brusilovsky.html' title='My interview with Daniel Brusilovsky'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=833032289943435889' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/833032289943435889'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/833032289943435889'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-343462069046631543</id><published>2007-09-28T23:21:00.000-07:00</published><updated>2007-09-28T23:43:16.180-07:00</updated><title type='text'>What's next?</title><content type='html'>&lt;p&gt;
&lt;a href="http://www.allthingsdistributed.com/"&gt;Werner Vogels&lt;/a&gt; on &lt;a href="http://en.wikipedia.org/wiki/Michael_Stonebraker"&gt;Michael Stonebraker&lt;/a&gt;'s 50X challenge:
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://www.allthingsdistributed.com/2007/09/50_x.html"&gt;&lt;blockquote&gt;
I like this challenge, given that 50X is likely to be able to make impact, where 2-4X in general can be easily compensated for by the next generation hardware. But something bugs me about the challenge and also about some of the demonstrations in the papers; 50X is still focused on scaling-up, just as many of the current database systems do, instead of scaling out, which is what the world really needs. The evidence in the paper is indeed about single box performance. This continuing N=1 thinking will never yield systems that can break through the current scalability limitations of enterprise software, regardless whether it runs 50 times faster or not.
&lt;/blockquote&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
I couldn't agree more. It's exciting to see so many people arguing for new kinds of databases, especially distributed databases. Why do I hate on relational databases? It's not the relational part, it's the part where they fail at 3am and wake me up. Joins are nice but I need my beauty sleep.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/09/whats-next.html' title='What&apos;s next?'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=343462069046631543' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/343462069046631543'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/343462069046631543'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-7781520936486448786</id><published>2007-09-21T22:39:00.001-07:00</published><updated>2007-09-22T00:01:20.707-07:00</updated><title type='text'>43 Folders makes the switch...</title><content type='html'>&lt;p&gt;
that I expect a number of others to follow. They just switched from a blogging system to a content management system. Lots of sites that have daily articles aren't blogs but  until recently it was easier to have separate blogs and auxiliary sites than to setup a full-blown CMS. These sites are easy to distinguish: they'll have forums, wikis, or other miscellany that aren't simply chronologically ordered notes of interest. For instance, 43 Folders has a Forum, Job Board, and sub-sites like gtd and &lt;a href="http://www.43folders.com/izero/"&gt;Inbox Zero&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
I always assumed CMS's would get easier to setup and use and some of the more popular sites would switch to them. I fully expect this to become a growing trend and am glad to see traditional blogging tools start to get some competition for serious users.
&lt;/p&gt;
&lt;small&gt;Update: Earlier, I mentioned in this post that &lt;a href="http://photomatt.net/"&gt;Matt&lt;/a&gt; pointed to a site that switched from WordPress to a CMS. I misread it. It was the other way around. Thanks, Jeremy. I hate it when you're right.&lt;/small&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/09/43-folders-makes-switch.html' title='43 Folders makes the switch...'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=7781520936486448786' title='4 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/7781520936486448786'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/7781520936486448786'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-3871995536171201341</id><published>2007-09-04T19:55:00.000-07:00</published><updated>2007-09-04T20:49:52.146-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='lift'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Putting my money where my mouth is</title><content type='html'>&lt;p&gt;
I've been going on and on about &lt;a href="http://scala-lang.org/"&gt;Scala&lt;/a&gt; and &lt;a href="http://liftweb.net/"&gt;&lt;em&gt;lift&lt;/em&gt;&lt;/a&gt; these past few months to pretty much anybody who would listen. &lt;em&gt;Lift&lt;/em&gt;, an alpha web framework for the object-functional language Scala, takes advantage of Scala's numerous features to provide a surprisingly powerful web framework in less than 10k lines of code. Take a look at the &lt;a href="http://liftweb.net/"&gt;lift&lt;/a&gt; site to get an idea of what it can do. &lt;small&gt;(Hint: David wrote a wiki in 45 lines of code)&lt;/small&gt;
&lt;/p&gt;

&lt;p&gt;
I can see it doing for Scala was Rails did for Ruby.
&lt;/p&gt;

&lt;p&gt;
So when &lt;a href="http://blog.circleshare.com/"&gt;David&lt;/a&gt; asked me if I wanted to be a committer, I jumped at the opportunity. I have a couple of patches going in my local SVN working copy mostly related to proper serving of MIME types and caching that I hope to get in soon.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/09/putting-my-money-where-my-mouth-is.html' title='Putting my money where my mouth is'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=3871995536171201341' title='4 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/3871995536171201341'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/3871995536171201341'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-5127976097264074932</id><published>2007-08-31T12:57:00.000-07:00</published><updated>2007-08-31T12:59:21.282-07:00</updated><title type='text'>Hacking the 46.</title><content type='html'>I love &lt;a href="http://sports.espn.go.com/espn/print?id=2977735&amp;type=story"&gt;this story&lt;/a&gt; where Matt Hasselbeck, based on what he's seen and heard on his home TiVo, "hacks" the Panther's defense.</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/hacking-46.html' title='Hacking the 46.'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=5127976097264074932' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/5127976097264074932'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/5127976097264074932'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-8093985276619863586</id><published>2007-08-19T21:38:00.000-07:00</published><updated>2007-08-20T09:51:13.865-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='systems'/><category scheme='http://www.blogger.com/atom/ns#' term='scalable'/><category scheme='http://www.blogger.com/atom/ns#' term='erlang'/><category scheme='http://www.blogger.com/atom/ns#' term='messaging'/><title type='text'>The future is messaging</title><content type='html'>&lt;p&gt; &lt;a href="http://intertwingly.net/blog/2007/08/12/Long-Bets"&gt;Sam
Ruby&lt;/a&gt; and &lt;a href="http://www.tbray.org/ongoing/When/200x/2007/08/13/Prognostication"&gt;Tim
Bray&lt;/a&gt; have each picked messaging systems as a trend to watch in the
future.  In particular, they are naming Jabber/XMPP as something to
watch. While I think XMPP is a great way to connect people to systems
or other people, I think there are better ways to connect systems to
systems.  &lt;/p&gt;

&lt;p&gt;
Enter &lt;a href="http://www.amqp.org/"&gt;AMQP&lt;/a&gt;, a protocol designed by the financial industry to replace their existing proprietary message queues with something built on open standards. The working group is made up of seasoned messaging profesionals who are used to having billions of dollars worth of transactions moving through their systems without mysterious delays or drops.
&lt;/p&gt;

&lt;p&gt;
There are two things that stand out in my mind about AMQP.
&lt;ol&gt;
&lt;li&gt;Payload Fidelity: Any stream of bytes you place in the payload will come out the other end the same way. At the end of this post, I show an example of this. If you can do this with Jabber, please say so. I certainly haven't seen a way to do it.&lt;/li&gt; 

&lt;li&gt;Queues instead of Buddy Lists: Instead of having human-centric buddy lists like with Jabber, you have accounts who have access to a namespace called a 'virtual host'. Inside of the 'virtual host' are named 'queue's and 'exchange's. Shove messages in one end and read them from the other.&lt;/li&gt; &lt;/ol&gt;
&lt;/p&gt;

&lt;p&gt; &lt;a href="http://www.rabbitmq.com/"&gt;RabbitMQ&lt;/a&gt; is an AMQP implementation built in Erlang and using &lt;a href="http://saladwithsteve.com/2005/02/mnesia_16.html"&gt;Mnesia&lt;/a&gt;.
Building clustered, high performance messaging systems in Erlang really
plays to that language's strengths, I feel. Erlang seems great at
shoveling bits from one network interface, &lt;a href="http://www.postneo.com/2007/08/10/erlang-bit-syntax-and-network-programming"&gt;doing
some pattern matching on them&lt;/a&gt;, changing some bits, and blasting
them out another interface.  &lt;/p&gt; 

&lt;p&gt;In my experience, you can have a
clustered rabbitmq setup running at home in under 20 minutes. It's all
in the &lt;a href="http://www.rabbitmq.com/admin-guide.html#clustering-transcript"&gt;admin
guide.&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;
Plus that question about transporting binary data over your messaging
layer? Here's a hack I wrote serializing Scala objects into
RabbitMQ and operating on them on the other side. It will work with
your default RabbitMQ installation:
&lt;/p&gt;

&lt;p&gt;
&lt;a href="http://sieve.net/websvn/filedetails.php?repname=Steve%27s+Happy+Time+Petri+Dish&amp;path=%2Fhacks%2FServer.scala"&gt;Server&lt;/a&gt;
&lt;br/&gt;&lt;a href="http://sieve.net/websvn/filedetails.php?repname=Steve%27s+Happy+Time+Petri+Dish&amp;path=%2Fhacks%2FClient.scala"&gt;Client&lt;/a&gt;
&lt;br /&gt;&lt;a href="http://sieve.net/websvn/filedetails.php?repname=Steve%27s+Happy+Time+Petri+Dish&amp;path=%2Fhacks%2FMain.scala"&gt;Multiplication class definition&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;
Anecdotally, I've heard that RabbitMQ can saturate a 100Mbps ethernet
connection with a single 3Ghz Pentium 4. I have a couple of quad core
opteron's (2x2 core) with 16G of RAM and multiple gigabit ethernet interfaces in
my basement; Seeing how much processing power is needed to saturate
a gigabit ethernet interface is definitely on my ToDo list!
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/future-is-messaging.html' title='The future is messaging'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=8093985276619863586' title='1 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/8093985276619863586'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/8093985276619863586'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-2759803282527136772</id><published>2007-08-17T19:37:00.000-07:00</published><updated>2007-08-17T19:42:39.593-07:00</updated><title type='text'>A real-life cold case.</title><content type='html'>Back in July, I received a jury duty summons. I didn't end up serving but it took 3 long days for the lawyers to finish selecting it. It was for &lt;a href="http://www.sfgate.com/cgi-bin/article.cgi?f=/c/a/2007/08/17/BALURK067.DTL&amp;amp;hw=john+davis&amp;amp;sn=001&amp;amp;sc=1000"&gt;a 20 year old rape and murder case&lt;/a&gt; considered San Francisco's first real Cold Case. It looks like that jury just entered deliberation.</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/real-life-cold-case.html' title='A real-life cold case.'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=2759803282527136772' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/2759803282527136772'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/2759803282527136772'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-1709355270873718353</id><published>2007-08-15T10:57:00.000-07:00</published><updated>2007-08-15T11:01:07.180-07:00</updated><title type='text'>I'm just BlueFlashin' my Apple ][, yo.</title><content type='html'>&lt;a href="http://vinchysky.angelfire.com/"&gt;BlueFlash&lt;/a&gt; is a "Bluetooth/Disk Controller/Disk Image Archive Card for Apple ][" that allows you to download files for the apple ][ onto your PC and transfer them to your Apple ][ via bluetooth.</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/im-just-blueflashin-my-apple-yo.html' title='I&apos;m just BlueFlashin&apos; my Apple ][, yo.'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=1709355270873718353' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/1709355270873718353'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/1709355270873718353'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-1225588828226828201</id><published>2007-08-14T21:14:00.000-07:00</published><updated>2007-08-14T21:27:13.679-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Weighted Slope One in Scala</title><content type='html'>&lt;p&gt;
&lt;a href="http://sieve.net/websvn/filedetails.php?repname=Steve%27s+Happy+Time+Petri+Dish&amp;path=%2Fslope_one%2Ftrunk%2Fsrc%2Fslope_one.scala"&gt;Here's&lt;/a&gt; a basic procedural version of &lt;a href="http://en.wikipedia.org/wiki/Slope_One"&gt;Weighted Slope One&lt;/a&gt; in Scala. It's pretty much a direct port of the &lt;a href="http://serpentine.com/wordpress/wp-content/uploads/2006/12/slope_one.py.txt"&gt;Python version&lt;/a&gt;. It's about 15 lines longer due to curly braces and Map syntax in Scala not having a few niceties that Python dictionaries have.
&lt;/p&gt;
&lt;p&gt;
Next I'm going to convert it to take advantage of Scala's powerful functional abilities. I'm going to take a stab to see if it lends itself to being a &lt;tt&gt;map&lt;/tt&gt; and &lt;tt&gt;reduce&lt;/tt&gt;. If that fails, I will fall back to good 'ol &lt;tt&gt;fold&lt;/tt&gt;. The goal will be for those &lt;tt&gt;for-comprehensions&lt;/tt&gt; to vanish and reveal an algorithm that's more parallelizable and then to run it on multiple cpus.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/weighted-slope-one-in-scala.html' title='Weighted Slope One in Scala'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=1225588828226828201' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/1225588828226828201'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/1225588828226828201'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-5418270692966270313</id><published>2007-08-10T21:48:00.000-07:00</published><updated>2007-08-11T23:07:26.260-07:00</updated><title type='text'>noatime</title><content type='html'>&lt;a href="http://kerneltrap.org/node/14148"&gt;Linus says: "&lt;span style="font-family:monospace"&gt;'noatime,data=writeback'&lt;/span&gt; will quite likely be *quite* noticeable (with different effects for different loads), but almost nobody actually runs that way."&lt;/a&gt; 
&lt;p&gt;
Well, if you need it, you &lt;strong&gt;really&lt;/strong&gt; need it. Otherwise, why would you ever care? I also don't believe in this 10% number people are spouting. How much it effects you will be determined by how many files you access. I think that should be fairly obvious. I've worked on systems that would crash after just a few minutes without noatime. Yikes!
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/noatime.html' title='noatime'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=5418270692966270313' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/5418270692966270313'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/5418270692966270313'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-8887843479505334665</id><published>2007-08-10T21:26:00.000-07:00</published><updated>2007-08-10T21:51:03.991-07:00</updated><title type='text'>Google meets with the Five Families for Linux patent protection.</title><content type='html'>&lt;blockquote&gt;
&lt;a href="http://www.channelregister.co.uk/2007/08/07/google_joins_open_invention_network/"&gt;
All OIN members - including big names such as IBM, NEC, Novell, Philips, Red Hat, and Sony, as well as Google - agree not to use their Linux-related patents against each other, and all have free access to a collection of additional open-source-related patents purchased by the consortium as a whole.
&lt;/a&gt;
&lt;/blockquote&gt;
&lt;p&gt;
&lt;a href="http://googleblog.blogspot.com/2007/08/joining-oin.html"&gt;
Seems like a good idea.&lt;/a&gt; Somebody will eventually have to take out Barzini, though.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/google-meets-with-five-families-for.html' title='Google meets with the Five Families for Linux patent protection.'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=8887843479505334665' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/8887843479505334665'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/8887843479505334665'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-7621335356529668942</id><published>2007-08-09T16:43:00.000-07:00</published><updated>2007-08-09T16:45:19.327-07:00</updated><title type='text'></title><content type='html'>&lt;a href="http://www.tigsource.com/features/games1-10.html"&gt;"50 Really Good Indie Games"&lt;/a&gt; Unfortunately, all of them look windows only. But there's a lot of fun, innovative games in here. At least, they &lt;strong&gt;look&lt;/strong&gt; fun and innovative from the screenshots.</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/50-really-good-indie-games.html' title=''/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=7621335356529668942' title='2 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/7621335356529668942'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/7621335356529668942'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-6212256707690880567</id><published>2007-08-05T17:08:00.000-07:00</published><updated>2007-08-05T17:46:52.619-07:00</updated><title type='text'>Time is an invention of man.</title><content type='html'>&lt;p&gt;
It's exceedingly unclear to pretty much everyone what I do with my time. This was pointed out by my cousin who just called and signed off with a sincere "Ok, have fun with.... well, whatever it is that you do."
&lt;/p&gt;
&lt;p&gt;
Let's take today as an example of what I do with my time.
&lt;ol&gt;
&lt;li&gt;Stinky the cat woke me up at 6am meowing about being hungry. As I am apprently elderly, I fell asleep at 10pm last night so it wasn't a big deal.&lt;/li&gt;
&lt;li&gt;I poured over an old wiki and imported the notes to sidenote, an "outboard brain" application for OS X.&lt;/li&gt;
&lt;li&gt;Wrote new notes after being inspired by these existing notes.&lt;/li&gt;

&lt;li&gt;Farted around with &lt;a href="http://developer.yahoo.com/yui/"&gt;YUI!&lt;/a&gt; for a frontend to my &lt;a href="http://liftweb.net/"&gt;lift&lt;/a&gt; app.&lt;/li&gt;

&lt;li&gt;Started writing a &lt;a href="http://en.wikipedia.org/wiki/Slope_One"&gt;Weighted Slope One&lt;/a&gt; algorithm in Scala. I was interrupted by lunch so I put that in OmniFocus' NextAction queue.&lt;/li&gt;

&lt;li&gt;Went to our nephew Kyo's &lt;a href="http://chinesefood.about.com/library/weekly/aa012303a.htm"&gt;Red egg and ginger party&lt;/a&gt; followed by a trip to Target.&lt;/li&gt;
&lt;li&gt;Played Burnout Revenge for the Xbox 360. I am currently 25% through the game, I should be done by the end of next week.&lt;/li&gt;
&lt;li&gt;Found several sets of instructions for installing Trac on dreamhost. I made a note in OmniFocus.&lt;/li&gt;

&lt;li&gt;Stacy programmed the universal remote we picked up at Target (more on that later)&lt;/li&gt;
&lt;li&gt;Investigated using an in-memory lucene index instead of something like Splunk. Serialized that into sidenote.&lt;/li&gt;

&lt;li&gt;My cousin called and signed off with the above quote.&lt;/li&gt;
&lt;li&gt;I wrote this stupid blog post.&lt;/li&gt;
&lt;li&gt;Will pick up work on the weighted slope one algorithm.&lt;/li&gt;
&lt;li&gt;Stacy and I will decide what's for dinner.&lt;/li&gt;
&lt;li&gt;Feed Stinky and Pudding and then retire for the evening.&lt;/li&gt;
&lt;li&gt;I'll pick one of the 3 books I'm currently reading and work through it.&lt;/li&gt;
&lt;li&gt;Fall asleep in a stupor complaining about something or other.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
Most days are a little different. Replace 'red egg and ginger party' with 'exercising' or 'loafing'. Also, I spend too much time using Google Reader, Twitter, and del.icio.us. At least I broke my programming.reddit habit.
&lt;/p&gt;</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/time-is-invention-of-man.html' title='Time is an invention of man.'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=6212256707690880567' title='3 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/6212256707690880567'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/6212256707690880567'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-3187374.post-7223998885962503149</id><published>2007-08-05T07:26:00.000-07:00</published><updated>2007-08-05T07:44:04.250-07:00</updated><title type='text'>NFL in HD</title><content type='html'>&lt;a href="http://www.hdsportsguide.com/nfl.php"&gt;HD Sports Guide&lt;/a&gt; has the low down on NFL games in HD this year. I only saw Monday Night Football in HD last year and so I'm excited to start seeing local games. DirecTV tries to squeeze nearly $400 out of you to see other teams in HD.

&lt;p&gt;
For those of you 49er's fans not local, here's the 4 games you can expect to see:
&lt;/p&gt;

&lt;pre&gt;
8/13/2007  Denver Broncos vs. San Francisco 49ers (Pre)  
8:00 PM ESPNHD (720p)

9/10/2007  Arizona Cardinals vs. San Francisco 49ers  
10:15 PM ESPNHD (720p)

11/12/2007  San Francisco 49ers vs. Seattle Seahawks  
8:30 PM ESPNHD (720p)

12/15/2007  Cincinatti Bengals vs. San Francisco 49ers  
8:15 PM      NFL Network (1080i)
&lt;/pre&gt;

If I remember last year, NFL Network HD runs on channel 96. It might be different this year.</content><link rel='alternate' type='text/html' href='http://saladwithsteve.com/2007/08/nfl-in-hd.html' title='NFL in HD'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=3187374&amp;postID=7223998885962503149' title='0 Comments'/><link rel='replies' type='application/atom+xml' href='http://saladwithsteve.com/atom.xml' title='Post Comments'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/7223998885962503149'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3187374/posts/default/7223998885962503149'/><author><name>Steve Jenson</name><uri>http://www.blogger.com/profile/09686593839106107926</uri><email>noreply@blogger.com</email></author></entry></feed>