<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:blogger="http://schemas.google.com/blogger/2008" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;CUEGSHoyeip7ImA9WhBVFU0.&quot;"><id>tag:blogger.com,1999:blog-14933935</id><updated>2013-04-20T20:20:29.492-04:00</updated><category term="Unix" /><category term="node.js" /><category term="Twitter" /><category term="Microsoft" /><category term="Metro" /><category term="Windows 8" /><category term="profanity" /><category term="javascript" /><category term="fuse" /><category term="apple" /><category term="plug-in" /><category term="Time Warner" /><category term="Review" /><category term="Windows" /><category term="recap" /><category term="browsers" /><category term="Mac OS X Server" /><category term="star wars" /><category term="MongoDB" /><category term="LightDesktop" /><category term="braydix" /><category term="considered harmful" /><category term="Chrome" /><category term="web 2.0" /><category term="spam" /><category term="PS2" /><category term="Mac OS X" /><category term="IPv4+" /><category term="email" /><category term="iOS" /><category term="qmail" /><category term="work" /><category term="FAIL" /><category term="linux" /><category term="IPv6" /><category term="macbook pro" /><category term="politics" /><category term="Wii" /><category term="Tumblr" /><category term="XML" /><category term="Blogger" /><category term="Google" /><category term="Total Annihilation" /><category term="AWS" /><category term="PHP" /><category term="NetServOS" /><category term="metrocard" /><category term="ruby on rails" /><category term="iPhone" /><category term="Firefox" /><category term="macbook air" /><category term="disks" /><category term="identity" /><category term="crestfs" /><category term="lucy" /><category term="Rant" /><category term="iPad" /><category term="mta" /><category term="health" /><category term="AIM" /><title>Brady's Blog</title><subtitle type="html">This is my blog. I know it's very hip for everyone to have had one already, but what do you want from me, I've been busy.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.uberbrady.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.uberbrady.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>153</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/brady" /><feedburner:info uri="brady" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;CUEGSHs5eCp7ImA9WhBVFU0.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-3781239603878807181</id><published>2013-04-20T20:20:00.002-04:00</published><updated>2013-04-20T20:20:29.520-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2013-04-20T20:20:29.520-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Metro" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows" /><category scheme="http://www.blogger.com/atom/ns#" term="Windows 8" /><category scheme="http://www.blogger.com/atom/ns#" term="iOS" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft" /><category scheme="http://www.blogger.com/atom/ns#" term="Mac OS X" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>Windows 8 from the point of view of a Mac user</title><content type="html">So I should mention before anything else that I use Windows 8 just for fun. I work all week on my Retina MacBook Pro in OS X, and on evenings and weekends - when I want to play World of Tanks - I reboot into Windows. That's about it. Make money on OS X, have fun in Windows. It's kinda like the opposite of how it was in the 90's (working in Windows, coming home to Mac).&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
So today when I launched World of Tanks, I realized I was in a bit of a rut, tank-wise. Quite a bit of XP in order to get the next set of tanks. What does that mean? Windows 8 upgrade time!&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
I was able to do the thing all online. $200. I would've liked to have stepped down from my Win 7 Pro down to Win 8 Home - I mean, all I do is game in the thing. Why do I need pro? But it didn't give me a chance. Upgrade assistant was pretty reasonable. It complained at me for not having enough space - I uninstalled some Steam games to make room, and when I flipped back to the Assistant window, it had moved along to the next screen. Not bad.&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
As my friend &lt;a href="http://beckleyworks.com/"&gt;Beckley&lt;/a&gt; and I have been discussing - Microsoft is &lt;em&gt;throwing&lt;/em&gt; money away not making it easier for Mac people to get Windows. And making it &lt;em&gt;way&lt;/em&gt; too expensive. If they put up an app in the App Store (presumably with Apple's buy-in) they could put a $99 price tag on it and make some nice money. At higher margins than OEM licenses! But they're dumb and short-sighted about things like that. Oh well.&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
Anyways, it still takes quite a few reboots for the install to complete. That was unexpected - but I guess that's me not remembering my Windows-fu. Kept having to hold down the Option (alt) key to get it to boot into Windows. It threw me into a setup assistant and I somehow managed to inadvertently hook up my Xbox account to my Windows login. Freaky, but why not.&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
I ended up hooking up my Metro Home screen to my Facebook account too, as well as my Xbox account. I was surprised to see Xbox avatars for all of my friends pop up - relatively easily accessible from the home screen as I clicked around. I had to download some updates and the process was not as buttery as possible, but still not bad at all. My FB friends are around too. Again, not too terrible. Hooked in two of my three Gmail accounts into the Mail app. In the end, I had a brand new view of all kinds of 'live tiles' giving me a newfangled view of my PC.&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
The Start button in Windows has always been a disaster for me - it contained a billion things I didn't care about, and 3 that I did. And when it had a scrolling view it was even worse. And that one view where it 'automatically' optimized where everything went? Even more of a disaster. So in Windows 8, Metro completely replaces the Start Menu. This new one actually makes sense to me. The three things I want to find? Right there, staring me in the face. I want to move them around? Easy and obvious. The &lt;em&gt;one&lt;/em&gt; place it consistently throws me for a loop is when I want to find something that I would normally have to dig through the lesser-used folders in the Start menu to find (Start -&amp;gt; Program Files-&amp;gt;SomeStupidCompanyName-&amp;gt;DumbUtility...). &lt;em&gt;That's&lt;/em&gt; where my muscle-memory gets in the way. I can't find something, I hit the 'command' key (Windows key) and the Metro screen comes up -&amp;gt; I can't find what I'm looking for -&amp;gt; I click on Desktop-&amp;gt; I still can't find what I'm looking for -&amp;gt; hit the Windows key again...&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
The 'flat' look seems timeless to me. Reminiscent of Star Trek:TNG's &lt;em&gt;LCARS&lt;/em&gt; pseudo-OS. No excessive curves and embossing and rounded edges and so on. Just really clean and flat. It starts to fall down a little bit when you look at Legacy Windows things - they look a little odd - trying to be flat like Metro but inheriting all the Windows baggage. And lots of things that are buttons don't look Buttoney. So I can imagine I will find myself in a position where I have to scrub my mouse around to see if things are clickable all the time. That will certainly cause some level of UI-fail. It'll be even worse on a touchscreen machine.&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
I'm even using IE10 (!) Because it shows up better on my Retina screen. I tried Google Chrome in 'Windows 8 mode' and it was ok - but the text was showing up too small. IE actually is not bad. I'm completely shocked by this. The font rendering still looks a touch off to me - some parts of letters look too thin maybe? I can't put my finger on it. But I can read the screen, and that's a nice start.&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
In the end, my feelings about the look/feel of the thing? I don't see why everyone is all up in arms. It's actually kinda futuristic-looking, IMHO. I actually find it very pleasant. Of course, I'm a bit of a contrarian - when I first used Windows Vista it didn't bother me as much as it seemed to bother everyone else. And when I first used Windows 7 I didn't think it was so super amazingly awesome like everyone else did. So take that into account. And also take into account - the only things I do in Windows are: play games, test things in IE, and poke around. I don't usually try too hard to get much work done. &lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
But as always, the devil is in the Details. And that's where Apple tends to really knock things out of the park, and where Microsoft tends to fumble. Especially when I click on something that's "classic" Windows from something that's Metro, things feel janky and weird and awkward. The tile layouts in the 'top free' and 'top paid' sections of the App store are awful and useless. I can't search the store either; if you don't click on one of the 'suggested' apps, you're screwed. The Skype integration seemed exciting - but then it was insisting on doing some kind of account merge that I didn't want it to do. I still can't figure out how to add a third email account. I can't get number of unread messages to show up in the email tiles. It's hard to get apps to show up in the Metro panel thingee if they aren't there already. Or if you (ahem) accidentally 'unpin' one (oops!). My Hipchat (Adobe Air) app was all messed up and confused and it took quite a bit of cajoling to get it so I could have a normal window on my screen. (That could be Adobe's fault, or HipChat's fault, or Microsoft's fault. Not sure.) As I continue to play with it, I'm sure I'll find more to complain about. I couldn't figure out how to open multiple windows in the Metro version of IE10 until I was doing final edits of this article (right-clicking somewhere plain on the page seems to bring up a contextual menu?) &lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
But in the end I think Microsoft is trying some really clever stuff here. I think this Metro stuff really is the future. Apple broke with OS X precedent when it made iOS; and I think Microsoft is trying to do the same thing here with Win8/Metro. And in the same way people were up in arms and completely freaked out when Apple first removed the Floppy drive - and then later, the CDROM - I think that's how the typical Microsoft person is responding to Metro.&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
I think Microsoft has latched on to Apple's "Halo Effect" strategy. Apple had the iPod, and the iPod "Halo" started to cause a boost in Mac sales (and lead to the iPhone and iPad). Analogously, Microsoft has the Xbox. Perhaps, from this Xbox Halo, they can start to rebuild the strength of their Windows empire? Maybe. But remember - Microsoft is adopting Apple's strategy here. And Microsoft was very good at taking someone else's idea or product, imitating it, iterating a few versions of it, throwing in some dubious business practices, and then coming up with something that actually starts to crush the competition. They might be trying that again here. Though they haven't really pulled that off in a while, I think.&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
My bet is that Microsoft-users will continue to whine and bitch and moan about how terrible and awful Windows 8 is. And we'll have a service pack or two come out, and then maybe some kind of interim release - and then maybe people will get used to it and move along.&lt;br&gt;&lt;br /&gt;
&lt;br /&gt;
I think, most importantly, that if they didn't obsolete themselves with Metro, someone else - probably Apple - would've done it for them. So they really had no choice.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/mn1kD6NIwLo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/3781239603878807181/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2013/04/windows-8-from-point-of-view-of-mac-user.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/3781239603878807181?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/3781239603878807181?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/mn1kD6NIwLo/windows-8-from-point-of-view-of-mac-user.html" title="Windows 8 from the point of view of a Mac user" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2013/04/windows-8-from-point-of-view-of-mac-user.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMFQHY-fSp7ImA9WhVXFU4.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-1852419017054975253</id><published>2012-04-15T20:33:00.000-04:00</published><updated>2012-04-15T20:33:31.855-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-04-15T20:33:31.855-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><title>In half-hearted defense of PHP</title><content type="html">Okay now there's a &lt;a href='http://me.veekun.com/blog/2012/04/09/php-a-fractal-of-bad-design/'&gt;big rant about PHP&lt;/a&gt;. These things are getting exhausting. I don't particularly like Python, that doesn't mean I have to make any kind of long boring post about it. It's just a matter of my personal preference, and I know that. Plenty of people do plenty of nice things in Python and that's great. Twisted seems like a cool idea. But I don't like Python. And no one cares, and no one should care.&lt;p&gt;&lt;br /&gt;
So the rant on PHP has a similar tenor to the ones about Node.js - which already starts us off on the wrong foot. However, as I read through the whole thing, I find that I can't disagree with any one particular point. Every single one seems at least conditionally valid, and at least none of them seem deliberate designed to be maliciously false. So, points to you sir and/or m'am on your post. My rebuttal follows.&lt;p&gt;&lt;br /&gt;
I've been using PHP for somewhere around 10 or 15 years or so, and I haven't run into even half of those various weird edge-cases. I'm not saying they don't exist. They seem like they do. But I'm saying you don't run into them so often.&lt;p&gt;&lt;br /&gt;
However, I do feel that the long, exhaustive list of 'things that are wrong with PHP' sort-of misses the point. Yes, the language has weird bugaboos about it. All languages do. No, none of them are fatal. The language is easy to pick up and be productive in. It's easy to have a mostly-static site with the odd dynamic page here and there. Deployment is a breeze. FTP up your new files and you're done. You don't even have to think about it. Sites run fast. Development is easy. The documentation is excellent. I haven't seen any other environment that comes remotely close in that regard. Just about any thing you would want to be able to do, there is a function for. It exists to make dynamic web pages, so it fits that well.&lt;p&gt;&lt;br /&gt;
The article also rather quickly breezes over an important point. Facebook uses PHP. Why is that? The article states that it's fine for FB because they're huge and can 'engineer around' the various weaknesses of the language. That certainly begs the question as to why they would bother. Is it just legacy? Are they just dumb? I have a hard time believing any of those possibilities.&lt;p&gt;&lt;br /&gt;
Mass hosting for websites really only works for PHP. The security gets a little dodgy, but it basically kinda works. Try that with any other webdev environment and you wont get nearly the server-density that you do in PHP. That is pretty hard to beat.&lt;p&gt;&lt;br /&gt;
Server-side includes. Anyone remember these? This is really what PHP has supplanted. For that kind of stuff, it's great.&lt;p&gt;&lt;br /&gt;
Or for a one-page site. Or a static site that has one dynamic page that does something - you &lt;i&gt;cannot&lt;/i&gt; beat PHP.&lt;p&gt;&lt;br /&gt;
Plenty of people use it with frameworks for complex sites. If I had a really super complex site to do, I honestly don't know whether or not I'd do it in PHP. But if I did decide to do it there, I wouldn't feel the least bit bad about it.&lt;p&gt;&lt;br /&gt;
Edit, reload, etc. You can edit a PHP page on a server, hit reload, and it works. No magic. Or if there is magic in that, it's so magical that you don't need to ever know how it works. This is quite pleasant. No dicking around with production versus development or HUP signals or restart.txt files or any of that shit. On development or production; edit your file, reload. Boom.&lt;p&gt;&lt;br /&gt;
Server infrastructure - since PHP is most often served up via Apache, you don't have to throw some kind of reverse proxy in front of it or anything. If you have static assets, they will be quickly served up via Apache's static web-page serving. All for free in the default set-up for PHP.&lt;p&gt;&lt;br /&gt;
Performance. PHP is fast. Even without an accelerator. I've built many, many PHP apps, and I've never needed to use one - the database always ends up being the bottleneck, never the web front-end. It will likely outperform most other web environments with no tuning. I *have* had to tweak the maximum number of http processes in Apache on a very high-traffic site, and I've also messed with the maximum PHP memory to permit per-process, but (off the top of my head) those are the only two knobs I've had to twiddle. And I've only had to do that on sites with the highest-of-traffic running on the crappiest-of-server environments.&lt;p&gt;&lt;br /&gt;
So if you want to live in your tiny ivory tower and yammer on endlessly on pedantic points about object hierarchies and namespace pollution and function-name consistency, feel free. However, those of us who are jamming out PHP sites will not be doing that - because we will have already finished the project we've worked on and moved on to the next one.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/w6KDjzyt_qU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/1852419017054975253/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2012/04/in-half-hearted-defense-of-php.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1852419017054975253?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1852419017054975253?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/w6KDjzyt_qU/in-half-hearted-defense-of-php.html" title="In half-hearted defense of PHP" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.uberbrady.com/2012/04/in-half-hearted-defense-of-php.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkIESHc9fyp7ImA9WhRbF08.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-855184023685446955</id><published>2012-02-08T12:01:00.001-05:00</published><updated>2012-02-08T12:01:49.967-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-02-08T12:01:49.967-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="MongoDB" /><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>Practical experience with Mongo, and why I do not like it, in terms of Money and Time</title><content type="html">For my job, I inherited a Mongo architecture. I resolved to learn it - and it still runs to this day, ticking along quite nicely.&lt;br /&gt;
&lt;br /&gt;
This is what my feelings are about the platform having actually used it in production - not on little toy projects. Our main MongoDB server is a 67 GB RAM AWS instance, with several hundred GB of EBS storage.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;First, the good parts:&lt;/h4&gt;&lt;br /&gt;
It's super-duper easy to set up and administer. Pleasant to do so, in fact.&lt;br /&gt;
&lt;br /&gt;
Javascript in the console is a remarkably useful thing to have handy. I've used it for quick proof-of-concepts and tests and whatnot - really good to have.&lt;br /&gt;
&lt;br /&gt;
It's really nice to develop against. Not having to deal with schema changes, and being able to save arbitrary column-value associations makes life really easy.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;And now, the bad (from unimportant to important)&lt;/h4&gt;&lt;br /&gt;
Doing anything beyond a really trivial or simplistic query in the console is surprisingly annoying:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;db.tablename.find({"name": {$gt: "fred"}})&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Not a dealbreaker or anything, just annoying. &lt;code&gt;name &amp;gt; "fred"&lt;/code&gt; would be nicer.&lt;br /&gt;
&lt;br /&gt;
The default 'mode' of Mongo is surprisingly unsafe. I found drivers (could be the driver's fault, might not be Mongo's) that return _immediately_ after you attempt a write - without even making sure the data has touched the disk. This makes me uneasy. But there are probably use cases for this kind of speed at the expense of safety. But I don't like it. And this is opinion, so I'm saying it. There _are_ modes that you can use (and I do use) that slow down the writes to make sure they've at least been accepted.  But, in the conventional mode, if we have a crash before the writes have been accepted by Mongo, the data is gone. This has happened to us. Usually we have failsafes in place to ensure that the data eventually gets written, but it costs us time. We're mortal; we're going to use the defaults we get until they don't work for us, then we're going to change them.&lt;br /&gt;
&lt;br /&gt;
Because there is no schema, a mongo "collection" (fuck it, I'm going to call it a table) takes up more storage than it should. Our large DB would be far smaller if we defined a schema and stored it in an RDBMS. This space seems to be taken up in RAM as well as disk. This costs us more money.&lt;br /&gt;
&lt;br /&gt;
MongoDB starts to perform horribly when it runs out of memory. This is by design. But it's annoying and it costs us more money and time because we have to either archive out old data (which we do in some cases), or use a larger instance than we ought to have to (which we also do). And even if you delete entries, or even truncate a table, the amount of space used on disk remains the same (see below). More money.&lt;br /&gt;
&lt;br /&gt;
MongoDB will fragment the storage its given if your data gets updated and changes size. This caused us to end up storing around 20-30 GB of data in a 60-some-odd GB instance. And then we started to exhaust RAM, and performance plummeted. So we needed to defrag it. More care and feeding (time) that I didn't want to spend.&lt;br /&gt;
&lt;br /&gt;
So to 'fix' the fragmented storage issue, we had to 'repair' the DB. This knocked our instance offline for hours. Many hours. Time. The standard fix for this is to spin up another instance (money), make it part of a replication set, repair one, let it catch up, then repair the other. Time.&lt;br /&gt;
&lt;br /&gt;
The final issue I had with Mongo was when I attempted to shard our setup. We were using a 67GB (quad-x-large memory) instance for our Mongo setup. I got advice from some savvy Mongo users to 'just shard it.' That made it sound so trivial. So I did. I figured we could go for 16GB shards and add a new one when we got heavy, and yank out one if we got light. I liked the idea of being able to save more money, and flexibly respond to requirements. So I set up a set of four shards - three "shardmasters" which coordinated metadata, and one 'dumb shard' which just stored data and synced up to the metadata servers. I blew the first time to get the config right. Whoops. I did it again, and this time, I did it right. I picked a shard key - not an ideal one, but one that would, over time, roughly evenly distribute data across all of our shards, while maintaining some level of locality for the most likely operations. I ran a test - it's really nice to do in the JS console, I must say. I ran a for-loop to insert 10 million objects of garbage data, with a Modulo-10 of 'i' to simulate the distributions of the shard keys. I watched, in a separate console, as it threw data on one shard, then started migrating data from one shard to the others. It worked enormously well. So I yanked my test data, then we put production data on the thing.&lt;br /&gt;
&lt;br /&gt;
It worked fine for a few days. The Mongo filled up a shard and blew up. It was a pretty huge, horrible catastrophe. It was hard for me to troubleshoot what, exactly, happened - but it looked like no data went onto any shard other than the first.&lt;br /&gt;
&lt;br /&gt;
Now, I *was* using an ObjectId() as the shard key. Not the object's _id, but the object_id of a related table. One that was nice and chunky - didn't change very much except for every few hundred thousand records or so. It's possible that I needed not to use a shard key that is an increasing ObjectId. It's possible that switching from an integer going from 0-9 over to an ObjectId that increments somehow messed me up. I tried to figure out what happened, after the fact, and got similarly nowhere. I also checked documentation to see if I had done something wrong. While I wasn't able to find anything definitive, there was mention about using an ObjectId as your shard key possibly throwing all traffic to just one shard. For our purposes, that would've been fine *if* the other 'chunks' of data got migrated off that shard, on to somewhere else. They didn't. This whole ordeal cost us loads and loads of time. Again, I'm perfectly willing to take the blame for having done something wrong - but if so, then there's something missing in the documentation.&lt;br /&gt;
&lt;br /&gt;
So that was a complete nightmare. But it's still not a technology I would discount - I can imagine specific use-cases where it might fit nicely. And it sure is pleasant to work with, as an admin and as a developer. But I'd far rather use something like DynamoDB (which seems very interesting), or something like Cassandra (which I've been following closely, but I have not yet put into production). In the meantime, I still use a lot of MySQL. And it definitely shows its age, and isn't always pleasant, but generally does not surprise me.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/EqPLZVqB5Zo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/855184023685446955/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2012/02/practical-experience-with-mongo-and-why.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/855184023685446955?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/855184023685446955?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/EqPLZVqB5Zo/practical-experience-with-mongo-and-why.html" title="Practical experience with Mongo, and why I do not like it, in terms of Money and Time" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.uberbrady.com/2012/02/practical-experience-with-mongo-and-why.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMAQn8_eCp7ImA9WhRbEEs.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-4297131548484189429</id><published>2012-01-31T21:51:00.000-05:00</published><updated>2012-01-31T22:20:43.140-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-31T22:20:43.140-05:00</app:edited><title>Amazon cloud-init - customizing EBS-backed Amazon Linux AMI's</title><content type="html">&lt;b&gt;EDIT&lt;/b&gt; - No, not even this works. I feel like I'm losing my mind.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;EDIT 2&lt;/b&gt; - Oh, apparently you *have* to specify the boot kernel. Have to. Can't use "use default" as I have been for, like, ever. Ugh. Angry.&lt;br /&gt;
&lt;br /&gt;
I just blew a horrible amount of time on this. I've burned many an AMI - based on ephemeral store and EBS-backed volumes. But trying to do it 'right' - with programmable private keys and whatnot - seemed to be out of my grasp, at least when using Amazon's own Linux distro.&lt;br /&gt;
&lt;br /&gt;
If you try to customize Amazon Linux you will find that some things that are normally done by cloud-init don't seem to work on your image. Namely, setting ssh keys. It works fine when you first boot the pristine Amazon image, but when you try to burn your own it won't seem to set the ssh keys properly.&lt;br /&gt;
&lt;br /&gt;
To set them, make sure you blow out the contents of /var/lib/cloud/ - and both /root/.ssh/authorized_keys as well as /home/ec2-user/.ssh/authorized_keys. They'll get reset on next boot.&lt;br /&gt;
&lt;br /&gt;
This isn't documented anywhere and I basically had to dick around with strace and flipping through all of the python code to figure out that there's a semaphore file in /var/lib/cloud/sem that gets set and then the ssh-setting-script at boot will never run again. It makes me angry - but maybe that's Amazon's point; they don't want you to customize their image so they can save on EBS volume space. I don't know. Pisses me off and wastes my time for sure though.&lt;br /&gt;
&lt;br /&gt;
You would think that at least when I try to run stuff by hand it would say "Oh, hey, there's a semaphore file right here - make sure to yank it if you really want to run your scripts again." Not this silent no-message bullshit.&lt;br /&gt;
&lt;br /&gt;
ARGH.&lt;br /&gt;
&lt;br /&gt;
-B.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/8zPsv3J9TgI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/4297131548484189429/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2012/01/amazon-cloud-init-customizing-ebs.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/4297131548484189429?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/4297131548484189429?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/8zPsv3J9TgI/amazon-cloud-init-customizing-ebs.html" title="Amazon cloud-init - customizing EBS-backed Amazon Linux AMI's" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2012/01/amazon-cloud-init-customizing-ebs.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YCQ3g-fSp7ImA9WhRUGUs.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-1710615904786314713</id><published>2012-01-30T17:03:00.000-05:00</published><updated>2012-01-30T17:06:02.655-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2012-01-30T17:06:02.655-05:00</app:edited><title>Follow up on Amazon Elastic Load Balancers and multi-AZ configuration</title><content type="html">I got a &lt;a href="http://www.uberbrady.com/2011/11/amazon-elastic-load-balancer-elb.html#comment-form"&gt;really good comment&lt;/a&gt; on my blog a day or so ago from a guy by the name of &lt;a href="http://www.blogger.com/profile/11553393679098152285"&gt;Mark Rose&lt;/a&gt; (that's the only link I have for him, sorry!) He mentioned that AWS multi-AZ load-balancing happens via DNS - which intrigued me - so I thought I'd mess with my test load balancer and see.&lt;br /&gt;
&lt;br /&gt;
He explained that each AZ gets its own DNS entry when you look up the load balancer - and that meshes exactly with what I'm getting. I do the DNS lookup for the LB, and get two IP addresses right now - and I'm assuming that each one corresponds to one of the LB's.&lt;br /&gt;
&lt;br /&gt;
But Amazon does some interesting DNS stuff - for instance, if you look up one of your 'public DNS names' of your instances from the _outside_, you get the instance's outside IP address. But if you look it up from the _inside_, you get the inside IP. I use this for configuration settings, when I want an instance to have a relatively-static internal IP. Instead of trying to pin down the IP, I set up an elastic IP for the instance, and use the permanent public DNS name for that IP as the _internal_ hostname for the instance. This way, if the instance reboots, I just have to make sure that the elastic IP address I've configured is still associated with it, and everything still works internally.&lt;br /&gt;
&lt;br /&gt;
I assume that traffic to the inside IP address is faster than bouncing back outside to the public address, then going back inside. I definitely know that it is cheaper - you don't pay for internal network traffic, only external.&lt;br /&gt;
&lt;br /&gt;
So my question is - what does it look like when you try to resolve the load balancer's DNS name from the _inside_ of Amazon AWS? Do you get the same outside IP addresses, or do you get internal ones instead? Since it seemed like AWS traffic 'tends' to be directed back to the same AZ it originated from, I expect to get different answers.&lt;br /&gt;
&lt;br /&gt;
So here's what I did. Set up an ELB with two AZ's - us-east-1a and us-east-1e. I installed apache and launched it on both. As soon as the ELB registered the instances as 'up', I did a DNS lookup from the outside to see what it resolved to.&lt;br /&gt;
&lt;br /&gt;
I got exactly two addresses - I'm assuming one points to one AZ, one to another.&lt;br /&gt;
&lt;br /&gt;
Then, I tried to resolve the same ELB DNS name from the _inside_. Weirdly enough, I *still* get both (outside) IP addresses! I didn't expect that.&lt;br /&gt;
&lt;br /&gt;
So now, I wonder, is there anything to 'bias' the traffic to one AZ or another? Or is it just the vagaries of DNS round-robin that have been affecting me?&lt;br /&gt;
&lt;br /&gt;
I changed the home pages on both apaches to report which AZ they're in. I then browsed-to, and curl'ed, the ELB name. The results were surprisingly 'sticky' - on the browser, I kept seeming to hit '1-a'. On curl, I seemed to keep hitting 1-e.&lt;br /&gt;
&lt;br /&gt;
What if I specifically direct my connections to one IP or another? Let's see.&lt;br /&gt;
&lt;br /&gt;
Since the ELB IP addresses seem to correspond, one-to-one, with AZ's, I thought I would be able to curl each one. I did, and consistently got the same AZ for each IP. One seems to be strongly associated to 1-a, and one to 1-e.&lt;br /&gt;
&lt;br /&gt;
So it seems the coarseness of the multi-AZ ELB load-balancing can be fully explained by the coarseness of using round-robin DNS to implement it.&lt;br /&gt;
&lt;br /&gt;
Something else to note - it seems like the DNS entries *only* have 60 second lifetimes. With well-behaved DNS clients (of which I will bet there are depressingly few), you should at *least* be able to end up changing the AZ you're banging into every 60 seconds. However, in my testing - brief though it may be - it seems to stay pretty 'sticky'.&lt;br /&gt;
&lt;br /&gt;
So what does this mean? I dunno - I feel like I want to do multi-AZ setups in AWS even less now. round-robin DNS is old-school, but at large enough scales does generally work. Though I wonder if heavily-hit web services API's like the ones my company provides fit will enough into that framework? I'm not sure.&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Session stickiness and multi-AZ setups&lt;/h4&gt;&lt;br /&gt;
Another question - how does this affect 'stickiness'? You can set an LB to provide sticky session support - but with this IP address shenaniganry, how can that possibly work?&lt;br /&gt;
&lt;br /&gt;
Well, weirdly enough - it actually does.&lt;br /&gt;
&lt;br /&gt;
I set an Amazon load-balancer-provided stickiness policy on my test LB. I curl'ed the name, and got the cookie. I then curl'ed the individual IP addresses for the load balancer, with that cookie set. And now, no matter which IP I hit, I keep getting the results from the same back-end server. So session-stickiness *does* break-through the load-balancer's IP-address-to-AZ associations, to always keep hitting the same back-end server.&lt;br /&gt;
&lt;br /&gt;
I wonder, what does the AWS-provided cookie actually look like? It seems like Hex, so let me see if I can decipher it.&lt;br /&gt;
&lt;br /&gt;
Since I don't know if anything scary is encoded therein, I won't post my cookie here, but when I tried to decipher it, I just got a bunch of binary gobbeldygook. Stayed consistent from request-to-request (maybe modulo time, not sure), so probably just encodes an AZ and/or an instance ID (and maybe time).&lt;br /&gt;
&lt;br /&gt;
&lt;h4&gt;Implications&lt;/h4&gt;&lt;br /&gt;
So since AWS exposes some of the internal implementation details of your load-balancer setups, what does this mean? It certainly does imply that you can lower the bar for DoS'ing a website that's ELB-hosted by just picking one of the ELB IP's and slamming it. For a two-AZ example - as opposed to having to generate 2x traffic to overwhelm a site, you can just pick one IP and hit that one with 1x and have the site go half-down from it.&lt;br /&gt;
&lt;br /&gt;
Considering the issues I've actually run into from having autoscaling groups that won't scale because only one AZ is overwhelmed, I wonder if it makes sense to only have autoscaling groups that span a single AZ?&lt;br /&gt;
&lt;br /&gt;
And it also seems to imply that you can DoS an individual server by hitting it with a session-cookie that requires it to always hit the same back-end server. So perhaps, for high-performance environments, it makes sense to stick with shared-nothing architectures and *not* do any kind of session-based stickiness?&lt;img src="http://feeds.feedburner.com/~r/brady/~4/aQorbj5PxgM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/1710615904786314713/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2012/01/follow-up-on-amazon-elastic-load.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1710615904786314713?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1710615904786314713?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/aQorbj5PxgM/follow-up-on-amazon-elastic-load.html" title="Follow up on Amazon Elastic Load Balancers and multi-AZ configuration" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.uberbrady.com/2012/01/follow-up-on-amazon-elastic-load.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEUNSHc-fCp7ImA9WhRXE0o.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-6175414662764166414</id><published>2011-12-20T05:17:00.001-05:00</published><updated>2011-12-20T05:18:19.954-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-12-20T05:18:19.954-05:00</app:edited><title>RightScale-to-Native Amazon Web Services (AWS) Name Synchronizer</title><content type="html">At my company, we use RightScale for a lot of our Amazon Web Services management. It's a pretty neat service - sort of "training wheels" for the cloud. Still provides us a lot of value.&lt;br /&gt;
&lt;br /&gt;
But sometimes I like to log directly into the AWS console. Especially to find out when Amazon has scheduled reboots of our servers. Before I wrote this script, I would log in to find a whole bunch of instances running with no names. Then I'd have to go look them up in RightScale. Why can't RightScale just name your Amazon instances with the right names?!&lt;br /&gt;
&lt;br /&gt;
Well, I finally took matters into my own hands and built the following script. It walks through all of your RightScale servers, and finds the associated Amazon instances and sets their name attributes to the RightScale "nicknames."&lt;br /&gt;
&lt;br /&gt;
And I got permission from my job to make it available to the public - so here it is:&lt;br /&gt;
&lt;br /&gt;
&lt;a href="https://github.com/uberbrady/RightScaleNameSynchronizer"&gt;https://github.com/uberbrady/RightScaleNameSynchronizer&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Yes, it is not the prettiest code I have ever written, but it does the trick. If someone wants to make it prettier I am definitely open to pull requests.&lt;br /&gt;
&lt;br /&gt;
One thing I have noticed is that when you 'relaunch' a RightScale instance, the new instance will come up without an AWS name. If you re-run the script that will fix that. Also, if you use any RightScale arrays, the same thing can happen during scale-up/scale-down events.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/fzvcwwXcqns" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/6175414662764166414/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2011/12/rightscale-to-native-amazon-web.html#comment-form" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6175414662764166414?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6175414662764166414?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/fzvcwwXcqns/rightscale-to-native-amazon-web.html" title="RightScale-to-Native Amazon Web Services (AWS) Name Synchronizer" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total><feedburner:origLink>http://www.uberbrady.com/2011/12/rightscale-to-native-amazon-web.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DU4MSH0_fCp7ImA9WhRSFU0.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-3457476072725362599</id><published>2011-11-16T20:33:00.000-05:00</published><updated>2011-11-17T00:33:09.344-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-11-17T00:33:09.344-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="node.js" /><category scheme="http://www.blogger.com/atom/ns#" term="AWS" /><title>Amazon Elastic Load Balancer (ELB) performance characteristics</title><content type="html">So at my new job, I get to use AWS stuff a lot. We have many, many servers, usually sitting behind a load-balancer of some sort. Amazon's documentation on these things isn't very clear, so I'm trying to figure out what the damned things are doing.&lt;br /&gt;
&lt;br /&gt;
First off - a good thing. These Load Balancers are really easy to use. Adding a new instance is a few clicks away using the Console.&lt;br /&gt;
&lt;br /&gt;
Another good thing - you can use multiple availability zones as a way to avoid trouble when an entire Availability Zone goes down (as happened less than a year ago). And here's where it gets ugly.&lt;br /&gt;
&lt;br /&gt;
It seems to evenly split traffic across zones - even if you don't have a balanced number of instances in each zone. And it seems to determine which zone to hit based on some hash of the source address. So, if you have 2 instances in an Autoscale group, in two availability zones, and you hit your array from one IP really hard - bad things ensue. The one AZ you're hitting will max out the CPU, and the AZ you're not hitting will be nearly 100% idle. That adds up to 50% utilization on average - not enough to cause a scaling event (with my thresholds, anyway).&lt;br /&gt;
&lt;br /&gt;
So, in short, if you have fojillions of people from all over hitting your services indiscriminately, I'm sure it'll be fine. But, if like me, you have 1000's of people (or so) from all over, some really hard from one particular IP - it may not be a good idea to try to spin up more than one AZ. And spinning up 4 AZ's seems silly - you'll definitely have more of a chance of at least one of them going bad, and until your load-balancer figures that out, you'll have one out of 'n' requests failing.&lt;br /&gt;
&lt;br /&gt;
Another thing I've noticed - the ELB's seem to have a strict timeout on accessing the back-end service. If it doesn't get a response within 30 seconds, it's going to drop the connection and hit the service again. I had a service that was nearly getting DOS'ed by the load balancer that way. Make sure you have sane timeouts.&lt;br /&gt;
&lt;br /&gt;
So the next thing I was curious about was whether or not the ELB would do any batching-together of any of the returned data - would it act like some kind of reverse-proxy? I wrote a tiny Node server which spat out a little data, waited 10 seconds, spat out some more, waited another 10 seconds, then finished. Here it is:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;#!/usr/local/bin/node&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;"use strict";&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;var http=require('http');&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;http.createServer(function (req,res) {&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; console.warn("CONNECTION RECEVIED - waiting 10 seconds: "+req.url);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; res.writeHead(200, {'Content-Type': 'text/plain'});&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; res.write("initial output...\n");&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; setTimeout(function () {&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;nbsp; console.warn("first stuff written for "+req.url);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;nbsp; res.write("Here is some stuff before an additional delay\n");&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;nbsp; setTimeout(function () {&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; console.warn("second stuff written for "+req.url);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; res.end('Hello World\n');&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; &amp;nbsp; },10000);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&amp;nbsp; },10000);&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;}).listen(80);&lt;/code&gt;&lt;br /&gt;
&lt;div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So - I couldn't tell any difference between hitting the server directly, or hitting the load balancer (if I telnetted straight to port 80). It acted the same way. There was definitely no batching.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
What about if I have a slow-client, or something that's trying to upload something - will it get batched together on the POST side?&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I modified my code to do a 'slow POST' - and it worked similarly - I couldn't actually tell the difference between running that on the load-balancer or running it on the instance directly.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
I also wrote code to generate a large (1MB) response dynamically on the server-side, then wrote a client that would receive a little, pause the stream, resume it after a few seconds, pause it again, and so on. The one thing I noticed different between accessing the server directly versus the load balancer was that the server tended to give me data in 1024 byte chunks, whereas the load-balancer was giving me blocks closer to 1500 bytes. Weird! Well, maybe not - I *do* know for sure that the LB is reterminating the connection at the TCP level - the source IP address changes. I was &lt;b&gt;writing&lt;/b&gt; the data in blocks of 1k, so maybe each write turned into exactly one packet of 1024 bytes? But in the LB side, the LB, when re-streaming my TCP data, was sending larger segments. Or so it would seem.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
So it looks like I &lt;b&gt;can't&lt;/b&gt; get rid of the reverse-proxy that sits on top of some of our Ruby code. Oh well.&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/brady/~4/rZ0a91t-ldg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/3457476072725362599/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2011/11/amazon-elastic-load-balancer-elb.html#comment-form" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/3457476072725362599?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/3457476072725362599?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/rZ0a91t-ldg/amazon-elastic-load-balancer-elb.html" title="Amazon Elastic Load Balancer (ELB) performance characteristics" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>4</thr:total><feedburner:origLink>http://www.uberbrady.com/2011/11/amazon-elastic-load-balancer-elb.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0INSXo7fyp7ImA9WhdbEEk.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-5796755458959942561</id><published>2011-10-07T22:39:00.000-04:00</published><updated>2011-10-07T22:39:58.407-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-07T22:39:58.407-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="node.js" /><title>More on (Moron?) Ted Dziuba</title><content type="html">(Math and pedantry ahead. Feel free to skip if that's not your thing. More stuff about Node.js and this guy Ted Dziuba, who I hate.) To start, read Mr. Dziuba's &lt;a href="http://teddziuba.com/2011/10/straight-talk-on-event-loops.html"&gt;latest blog rant about Node.js.&lt;/a&gt;&lt;p&gt;
I will make two main points here. First, that Mr. Dziuba does not intend to be comprehended; that he is deliberately phrasing points so as to confuse. Second, I will prove that his arguments are invalid. It appears to me that he has no interest in deriving any kind of truth or shedding any light on anything; he is merely trying to draw attention to himself, or draw blog traffic, or just make noise. I don't know what his reasons are. I just know what he's doing, and that seems to be being deliberately misleading. I would not feed the troll, as it were, except for the fact that his blog post is permanently on the internet and I'm going to end up being pointed to it someday if I ever propose an event-loop based solution for anything.&lt;p&gt;
First off, let's try to decipher what he's saying; he does not do a very good job of being clear.&lt;p&gt;
Let's look at Theorem 1.&lt;p&gt;
What does it actually say? Here's an &lt;i&gt;attempt&lt;/i&gt; at deciphering it.&lt;p&gt;
He asks, let's check out how things work when you have something that's heavily CPU-biased (less I/O).&lt;p&gt;
Note = the value 'k' is the ratio of I/C - in other words, for something really really IO intensive (I &amp;gt; C) then k should be 'big' (greater than one), and for I &amp;lt; C, k should be small (less than one). You can think of 'k' as the "IO-ish-ness" factor. It's big for something that's very IO-ish, and it's little if it's not. Why doesn't he explicitly state the definition that k=I/C? Because he has no desire to be understood; he's attempting hand-waving. Everywhere he uses this 'k' construct he could just as easily use I &amp;amp; C.&lt;p&gt;
The important definition is: W=I+C=kC+C=(k+1)C&lt;p&gt;
Therefore K is I/C&lt;p&gt;
(k+1)C is equal to W = the wall clock time of I + C.&lt;p&gt;
His theorem begins with the supposition:&lt;p&gt;
1000/C  &amp;gt; 1000N/(k+1)C&lt;p&gt;
What does that mean?&lt;p&gt;
Let's change his equation to make more sense of it. Since (k+1)C=(I+C) by definition, he's really just saying:&lt;p&gt;
1000/C &amp;gt; 1000N/(C+I)&lt;p&gt;
He's trying to suppose that &lt;b&gt;*IF*&lt;/b&gt; the number of times I can execute just the CPU-part of my event-loop code is greater than the number of times I can do that, threaded, but also with I/O time taken into account, &lt;b&gt;*THEN*&lt;/b&gt; it must be the case that the number of threads I am using is one. Why would you make the argument like that? The same argument can be made, much more simply, by saying:&lt;p&gt;
1000/(C+I) &amp;gt; 1000N/(C+I) only if N is one. But the problem is then you can see what he's doing. He doesn't want this, hence the pointless variable substitution.&lt;p&gt;
Notice that 'N' factor on there? He is saying that a system with 2 threads runs twice as fast as a system with one thread. And apparently a system with 100 threads runs 100 times as fast as a system with one thread. I've worked with much software throughout my personal and professional life, and this supposition is not true. By this assumption, of course threads will always outperform event-loop software.&lt;p&gt;
He attempts the same song-and-dance in Theorem 2. He still is making the assumption that N threads equals N*single-threaded performance.&lt;p&gt;
It's most clear in his "Practical Example." There, you can see him making the n-threads-means-n-times-performance argument most clearly. If that's true, why not 1000 threads? Why not a million?&lt;p&gt;
Another point here. Why threads? Why not fully fork()'ed processes? His math (such as it is) still holds up just the same if you assume forked contexts as threaded. And, yet, none of his math requires threads instead of forks to run. &lt;p&gt;
Effectively, he has proven that in a system with an infinite number of infinitely fast CPU's, and infinite RAM, and zero threading context-switch time, and zero thread-accounting time, that threads are faster than events. Congratulations.&lt;p&gt;
So there are my arguments as to why he is incorrect. Now I wish to ask questions about how he seems to be deliberately misleading.&lt;p&gt;
First off - some stylistic questions. Why has he written his argument so obtusely? Why has he not shown his work? Why does he not explain what he's supposing? He just throws symbols down, in beautiful little .PNG files, and runs off with manipulating them with algebra. That's seems like he's trying an "appeal to authority" via jargon. Why all the milliseconds everywhere? We're in theoretical Comp Sci world now, why pick those units? It would appear that he has done so specifically to throw 1000's in his equations everywhere, just to confuse things further.&lt;p&gt;
Next - a more theoretical question. Why do things like the select() or poll() system calls exist? Or epoll or /dev/poll? Since they're so "obviously" inferior to threading-based solutions, they shouldn't exist at all, right? There should be no use for them. If I can always just use threaded I/O instead of event-looped, why use event-looped at all? It is, after all, very difficult to program.&lt;p&gt;
And finally - why did Dziuba himself advocate for an event-based I/O solution - "eventlet" - in &lt;a href="http://teddziuba.com/2010/02/eventlet-asynchronous-io-for-g.html"&gt;one of his own blog posts?&lt;/a&gt; He seems to have gotten quite the performance boost - &lt;p&gt;
&lt;blockquote&gt;
...but the one that really stands out in the group is Eventlet. Why is that? Two reasons:&lt;br /&gt;

1. You don't need to get balls deep in theory to be productive with Eventlet.&lt;br /&gt;
2. You need to modify very little pre-existing code to adapt a program to be event-driven.&lt;br /&gt;
&lt;br /&gt;
...&lt;br /&gt;
&lt;br /&gt;
This all sounds great in theory, but I have actually made a large I/O bound program work using monkey patching and changing the driver. It is a piece of software that reads jobs from a queue and processes them, putting the result in memcached. For esoteric reasons I will not go into, the job processors could not thread the work, they had to fork. Using this setup, one production box with 8GB of RAM was consistently 7.5GB full. After a less than 5 line code change to the driver, that same production box uses only around 1GB of RAM consistently, and can handle 5 to 10x the throughput of the old system.&lt;/blockquote&gt;&lt;p&gt;

The answers to these questions I cannot be sure of. As much as I would like to imagine that Mr. Dziuba is simply terribly ignorant; it would seem far worse - that he just intends to say things that are untrue for the purpose of drawing attention to himself.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/8CmCZqLss00" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/5796755458959942561/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2011/10/more-on-moron-ted-dziuba.html#comment-form" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/5796755458959942561?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/5796755458959942561?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/8CmCZqLss00/more-on-moron-ted-dziuba.html" title="More on (Moron?) Ted Dziuba" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>5</thr:total><feedburner:origLink>http://www.uberbrady.com/2011/10/more-on-moron-ted-dziuba.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DE4NR3w4fSp7ImA9WhdUFkg.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-5191493196377140986</id><published>2011-10-03T11:16:00.003-04:00</published><updated>2011-10-03T11:49:56.235-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-10-03T11:49:56.235-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="node.js" /><title>Node.js is not a cancer, you are just a moron</title><content type="html">My tone is going to seem strangely even and un-ranty. This is because I am doing everything I can to keep myself from completely exploding when I read this bullshit that this moron is spewing. OK, that was a little ranty, but the rest will read evenly. Maybe.&lt;p&gt;

So one of my programming friends posts an article at http://teddziuba.com/2011/10/node-js-is-cancer.html and says, "Ah, &lt;i&gt;here's&lt;/i&gt; what's wrong with Node.js!"&lt;p&gt;

The article is rather strongly written - "Node.js is Cancer", "node.js nonsense", "Node.js is a tumor on the programming community", "completely braindead", "Scalability disaster", etc.&lt;p&gt;

He then shows a Fibonacci sequence and how it performs badly under node.&lt;p&gt;

The problem he has proposed is, fundamentally, CPU-bound. I wrote a version of it in C and it did perform faster than it did in Node, but still, the problem definitely took finite-time. My command-line Node.js version calculated the answer in 8 seconds, the C version did it in 4. I was rather impressed that Javascript (Node.js's V8 engine) was able to come as close to C's performance in pure CPU-bound execution.&lt;p&gt;

The problem, and what the author perhaps misunderstands, is that this is not the situation in which Node is an ideal solution. I use Node.js in production for work - and I know of many other shops that do too. If the problems you are dealing with are CPU-related, Node.js will not help you. Node.js works well when your problems are I/O-related -e.g., reading something out of a database, running web servers, reading files, writing files, writing to queues, reading from queues, reading from other web services, aggregating several web services together, etc. The reason that this solution has become so popular of late is because these are the types of problems that are most common in web development today. Thus, node.js becomes a helpful arrow in one's quiver with which to solve these types of issues.&lt;p&gt;

Considering that the article's author seems to have some level of experience, I wonder if his choice of skewed example was perhaps deliberate. He has other articles on his blog about other event-loop libraries. His comment at the bottom - "tl;dr - Node.js is an unpleasant software library and I will not use it" - is possibly the real source of his anger. And - an irrefutable point - if you don't like something, you don't want to use it, and he obviously doesn't. That's fine.&lt;p&gt;

Node is a tool; one of many - no panacea. If you're dealing with problems of 'slow' services that need to wait for various bits of I/O to complete in order to return a result - it can be a very powerful and useful tool. If you're computing the fortieth member of the fibonacci sequence recursively, it won't be.&lt;p&gt;

The sad fact is that the author's &lt;i&gt;completely valid&lt;/i&gt; point - that Node.js isn't a good tool for CPU-bound problems - is completely buried in his bile. This is because he never states that, explicitly. Node.js has other drawbacks as well - it's very easy to end up in callback-spaghetti, it's very minimal, and it's very very very young. The database integration libraries have some pretty serious immaturity issues to work through; and I've had to code around a good deal of that.&lt;p&gt;

It's a tool that's good at particular things, and I will continue to use it for those things. Those 'things' tend to be the bulk of what web development and web services development actually &lt;i&gt;are&lt;/i&gt;. So when I can write a two hundred line program that can replace entire arrays of servers and interconnected services with just one server; I am going to do that, and I won't feel particularly braindead in doing so.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/GAWZsbtlPY0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/5191493196377140986/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2011/10/nodejs-is-not-cancer-you-are-just-moron.html#comment-form" title="8 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/5191493196377140986?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/5191493196377140986?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/GAWZsbtlPY0/nodejs-is-not-cancer-you-are-just-moron.html" title="Node.js is not a cancer, you are just a moron" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>8</thr:total><feedburner:origLink>http://www.uberbrady.com/2011/10/nodejs-is-not-cancer-you-are-just-moron.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkQMQHo9eip7ImA9WhdWFE4.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-7350257321998022506</id><published>2011-09-07T18:18:00.010-04:00</published><updated>2011-09-07T19:33:01.462-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-09-07T19:33:01.462-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="javascript" /><category scheme="http://www.blogger.com/atom/ns#" term="node.js" /><title>node.js scope weirdity</title><content type="html">So I've been using Node.js a lot in my new job. Quick note: it's super awesome. The job, and node.js. Anyways. I've put together a couple of non-trivial pieces with it and one thing that keeps tripping me up is: when is my variable in and out of scope? So I thought I'd write this up to see if I can explain it.&lt;p&gt;

&lt;h2&gt;First example&lt;/h2&gt;
Let's look at this simple server code - it's just a dumb webserver (shamelessly stolen from the node.js home page) that says 'hello world' and spits out a connection count:&lt;p&gt;

&lt;code&gt;&lt;pre&gt;
var http = require('http');
var conncount=0;
http.createServer(function (req, res) {
  conncount++;
  num=conncount;
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write("Here is some stuff\n");
  res.write("And the connection count is: "+conncount+"\n");
  setTimeout(function() {
   res.end('Hello World: conn count was: '+conncount+' and my connection # is: '+num+'\n');
        conncount--;
  },5000);
}).listen(1337, "127.0.0.1");


console.log('Server running at http://127.0.0.1:1337/');
&lt;/pre&gt;&lt;/code&gt;

So if I just curl that (&lt;code&gt;curl http://localhost:1337/&lt;/code&gt;), I get:&lt;p&gt;

&lt;code&gt;&lt;pre&gt;
Here is some stuff
And the connection count is: 1
&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;
...5 seconds pass, and then...&lt;p&gt;
&lt;code&gt;Hello World: conn count was: 1 and my connection # is: 1&lt;/code&gt;&lt;p&gt;

So that seems to make some sense. However, what happens if I run the code 12 times? This:&lt;p&gt;

&lt;code&gt;&lt;pre&gt;

Here is some stuff
And the connection count is: 1
Here is some stuff
And the connection count is: 2
Here is some stuff
And the connection count is: 3
Here is some stuff
And the connection count is: 4
Here is some stuff
And the connection count is: 5
Here is some stuff
And the connection count is: 6
Here is some stuff
And the connection count is: 7
Here is some stuff
And the connection count is: 8
Here is some stuff
And the connection count is: 9
Here is some stuff
And the connection count is: 10
Here is some stuff
And the connection count is: 11
Here is some stuff
And the connection count is: 12
&lt;/pre&gt;&lt;/code&gt;
...then 5 seconds elapse, then...
&lt;code&gt;&lt;pre&gt;
Hello World: conn count was: 12 and my connection # is: 12
Hello World: conn count was: 11 and my connection # is: 12
Hello World: conn count was: 10 and my connection # is: 12
Hello World: conn count was: 9 and my connection # is: 12
Hello World: conn count was: 8 and my connection # is: 12
Hello World: conn count was: 7 and my connection # is: 12
Hello World: conn count was: 6 and my connection # is: 12
Hello World: conn count was: 5 and my connection # is: 12
Hello World: conn count was: 4 and my connection # is: 12
Hello World: conn count was: 3 and my connection # is: 12
Hello World: conn count was: 2 and my connection # is: 12
Hello World: conn count was: 1 and my connection # is: 12
&lt;/pre&gt;&lt;/code&gt;

So my question is, why does it do that? Each execution of my function _should_ have its own stack, no? And so wouldn't each stack have its own variables?&lt;p&gt;

Now, mind you - I know a (horrible) way to fix this - wrap my setTimeout call in an anonymous function and pass 'num' as a parameter - but what I don't really get is 'why'? I threw this line all the way at the end (with apologies to Haddaway) - &lt;p&gt;

&lt;code&gt;setTimeout(function() { sys.debug("What is num! Baby don't hurt me, don't hurt me, no more..."+num)},10000);&lt;/code&gt;&lt;p&gt;

(And I had to &lt;code&gt;require('sys')&lt;/code&gt; at the top too)&lt;p&gt;

And, in my terminal with Node running, I got:&lt;p&gt;

&lt;code&gt;
DEBUG: What is num! Baby don't hurt me, don't hurt me, no more...12
&lt;/code&gt;&lt;p&gt;

What?! I would've expected 'num' to fall out of scope?! Why wouldn't that function scope up there make 'num' only exist for this execution? Is there no concept of 'stack' or anything? And even if there wasn't any, each execution of my function is an execution and should 'freeze' the variable or something, right? Apparently not.&lt;p&gt;

So what happened? Well, I can tell you - that variable 'num' that I referenced, since I *didn't* define it using 'var', is GLOBAL. So that's why it's acting so global. Simply adding 'var' to the definition (&lt;code&gt;var num=conncount;&lt;/code&gt;) made it start working properly. E.g., after the delay, my output became:&lt;p&gt;

&lt;code&gt;&lt;pre&gt;
Hello World: conn count was: 12 and my connection # is: 1
Hello World: conn count was: 11 and my connection # is: 2
Hello World: conn count was: 10 and my connection # is: 3
Hello World: conn count was: 9 and my connection # is: 4
Hello World: conn count was: 8 and my connection # is: 5
Hello World: conn count was: 7 and my connection # is: 6
Hello World: conn count was: 6 and my connection # is: 7
Hello World: conn count was: 5 and my connection # is: 8
Hello World: conn count was: 4 and my connection # is: 9
Hello World: conn count was: 3 and my connection # is: 10
Hello World: conn count was: 2 and my connection # is: 11
Hello World: conn count was: 1 and my connection # is: 12
&lt;/pre&gt;&lt;/code&gt;

Such a terribly easy way to blow up your javascript! So apparently node.js supports "strict mode" - just make the first line of your javsascript code say:&lt;p&gt;

&lt;code&gt;"use strict";&lt;/code&gt;&lt;p&gt;

(Note, that's just a string, &lt;b&gt;with&lt;/b&gt; the quotes. A javascript parser will just ignore it if it doesn't understand it. You could also put a line in the middle of your code saying &lt;code&gt;"poop";&lt;/code&gt; and it would be ignored the same way).
Now with strict mode enabled, the previous version of my code (without the 'var' declaration) says:&lt;p&gt;

&lt;code&gt;
ReferenceError: num is not defined
&lt;/code&gt;&lt;p&gt;

So I think I'll be using this from now on. Unless 'strict' mode starts making me crazy - which is certainly also possible.&lt;p&gt;

&lt;h2&gt;Next Example&lt;/h2&gt;
&lt;code&gt;&lt;pre&gt;
"use strict";
var sys=require('sys');
for(var i=0;i&lt;10;i++) {
 setTimeout(function() {sys.debug("I is now: "+i)},1000);
}
&lt;/pre&gt;&lt;/code&gt;

(Notice how I've learned my lesson? Yeah, I don't need concurrency bugs biting me in the ass, thankyouverymuch.)&lt;p&gt;

The output is, unfortunately:

&lt;code&gt;&lt;pre&gt;
DEBUG: I is now: 10
DEBUG: I is now: 10
DEBUG: I is now: 10
DEBUG: I is now: 10
DEBUG: I is now: 10
DEBUG: I is now: 10
DEBUG: I is now: 10
DEBUG: I is now: 10
DEBUG: I is now: 10
DEBUG: I is now: 10
&lt;/pre&gt;&lt;/code&gt;

So this one - I definitely know how to fix. The problem is that by the time the timeout actually _fires_, the value of 'i' will be different - in this case, incremented all the way to 10. I need to somehow 'freeze' the value of i within the timeout.&lt;p&gt;

So I would do:&lt;p&gt;

&lt;code&gt;&lt;pre&gt;
"use strict";
var sys=require('sys');
for(var i=0;i&lt;10;i++) {
 setTimeout((function(number) {return function() {sys.debug("I is now: "+number)}})(i),1000);
}
&lt;/pre&gt;&lt;/code&gt;

Which results in:
&lt;code&gt;&lt;pre&gt;
DEBUG: I is now: 0
DEBUG: I is now: 1
DEBUG: I is now: 2
DEBUG: I is now: 3
DEBUG: I is now: 4
DEBUG: I is now: 5
DEBUG: I is now: 6
DEBUG: I is now: 7
DEBUG: I is now: 8
DEBUG: I is now: 9
&lt;/pre&gt;&lt;/code&gt;

The problem is, that's ugly as shit. What better way to do it is there that's more readable, maintainable, debuggable, etc? And that function instantiation thing gives me the willies. Well, I don't know the best answer for that yet. How about this:&lt;p&gt;

&lt;code&gt;&lt;pre&gt;
"use strict";
var sys=require('sys');
for(var i=0;i&lt;10;i++) {
 (function(number) {
  setTimeout(function() {sys.debug("I is now: "+number)},1000);
 })(i);
}
&lt;/pre&gt;&lt;/code&gt;

(The output is still the same). That feels a little less awful and unreadable - and doesn't give me the anonymous-function-returning-function yucky feelings that the previous one did. (Though it still is effectively doing that, isn't it?) The crazy squiggly brace, close-paren, open-paren business is still a little awkward though.&lt;p&gt;

A piece of advice I got from the node.js group seemed pretty sage, in terms of making this stuff more readable:&lt;p&gt;

&lt;code&gt;&lt;pre&gt;
"use strict";
var sys=require('sys');

function make_timeout_num(number)
{
 setTimeout(function() {sys.debug("I is now: "+number)},1000);
}

for(var i=0;i&lt;10;i++) {
 make_timeout_num(i);
}
&lt;/pre&gt;&lt;/code&gt;

(output is still the same again). And, wow, yeah, that's a hell of a lot more readable, at the expense of 4 or so more lines. But sometimes, logically, you don't want to split out your functions like that - if every time you need to freeze something in a scope you have to declare a function somewhere, your eyes will have to scan all over the place, and that could be ugly. So you could maybe declare the function within the for loop - though that's still in the global scope, it would just be for readability's sake.&lt;p&gt;

I think I'll probably stick with the previous one, with the anonymous function declared in-line. It's not &lt;i&gt;too&lt;/i&gt; insanely unreadable, and it's compact enough. If the contents of my anonymous function gets a few lines long, or gets a few variables deep, I might split it out into its own function for readability's sake.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/4YwbRExcZ7E" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/7350257321998022506/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2011/09/nodejs-scope-weirdity.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/7350257321998022506?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/7350257321998022506?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/4YwbRExcZ7E/nodejs-scope-weirdity.html" title="node.js scope weirdity" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2011/09/nodejs-scope-weirdity.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYDRH07fip7ImA9WhZbGUg.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-3512663352288798677</id><published>2011-06-24T17:02:00.005-04:00</published><updated>2011-06-24T17:49:35.306-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-06-24T17:49:35.306-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="FAIL" /><category scheme="http://www.blogger.com/atom/ns#" term="plug-in" /><category scheme="http://www.blogger.com/atom/ns#" term="Firefox" /><title>Firefox 5 extensions compatibility woes</title><content type="html">Didn't find this on the intertubes anywhere, so I thought I would write it down to help somebody else with the problem.&lt;p&gt;

The new Firefox 5 disabled a lot of my plug-ins. You can disable the plug-in compatibility check by doing the following:&lt;p&gt;

Launch FF5, go to "about:config"&lt;p&gt;

Right click to add a new property, make it of type 'Boolean', name: extensions.checkCompatibility.5.0&lt;p&gt;

Set it to 'false'.&lt;p&gt;

Restart.&lt;p&gt;

You're welcome.&lt;p&gt;

(Oh, and I should mention, any previously disabled plug-ins are now re-enabled. Good point, &lt;a href='http://beckleyworks.com'&gt;Beckley&lt;/a&gt;.)&lt;img src="http://feeds.feedburner.com/~r/brady/~4/vJVWxl0he1s" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/3512663352288798677/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2011/06/firefox-5-extensions-compatibility-woes.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/3512663352288798677?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/3512663352288798677?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/vJVWxl0he1s/firefox-5-extensions-compatibility-woes.html" title="Firefox 5 extensions compatibility woes" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.uberbrady.com/2011/06/firefox-5-extensions-compatibility-woes.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEYAQXc7eyp7ImA9Wx9bE04.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-1696537213344473202</id><published>2011-02-21T16:24:00.003-05:00</published><updated>2011-02-21T18:49:00.903-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-21T18:49:00.903-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IPv4+" /><category scheme="http://www.blogger.com/atom/ns#" term="IPv6" /><title>A Modest Proposal...</title><content type="html">Had a great discussion via Twitter and my blog's comments about some stuff about IPv6 and other ways of handling the IPv4 address space shortage. Over the course of discussing things and arguing stuff and going back and forth, I think I've sharpened my idea.&lt;p&gt;
&lt;h2&gt;IPv4+&lt;/h2&gt;
IPv4+ is an extension of IPv4 address-space via backwards-compatible use of the IPv4 'Options' fields. Two such options shall be used, one for an 'extended-address-space' destination, one for 'extended-address-space' source. If these fields are used, they MUST be the first two options in the packet. If both extended-source and extended-destination options are used, the destination MUST be first. This enabled (eventual) hardware-assisted routing at a fixed offset within the IPv4 header. Extended addresses grant an additional 16 bits of address space. If any routing decisions are to be made based upon extended address space, those SHOULD only be done at an intra-networking layer, within one autonomous system. The extended source and extended destination options are exactly 32-bits long, each. The format is as follows:

&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Bits&lt;/th&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;1-2&lt;/td&gt;&lt;td&gt;3-7&lt;/td&gt;&lt;td&gt;8-15&lt;/td&gt;&lt;td&gt;16-31&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Field&lt;/th&gt;&lt;td&gt;Copied&lt;/td&gt;&lt;td&gt;Class&lt;/td&gt;&lt;td&gt;Number&lt;/td&gt;&lt;td&gt;Length&lt;/td&gt;&lt;td&gt;Data&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;th&gt;Values&lt;/th&gt;&lt;td&gt;1&lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;td&gt;5/6&lt;/td&gt;&lt;td&gt;3&lt;/td&gt;&lt;td&gt;Address Data&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;

Option 5 will be used for Extended Destination, and Option 6 will be used for Extended Source. Perhaps additional options could be reserved and specified for future use as "Super-Extended Destination" and "Super-extended Source". &lt;p&gt;

IPv4+ addresses will be specified in text as having two additional octets - e.g. 72.14.204.99.56.43. The extra octets on the right-hand side correspond to the extra 16 bits of addressing data. An address with both additional octets of zero is understood to mean a legacy IPv4 node at that address. E.g. 72.14.204.99.0.0 means the IPv4 node at 72.14.204.99.&lt;p&gt;

Operation of the protocol will be designed to be as backwards-compatible with Unextended IPv4 as possible.&lt;p&gt;

IPv4+ nodes have both an IPv4 address - which may be an RFC1918 non-routable address, or a link-local address - as well as an extended IPv4+ address, which SHOULD be a routable IPv4 address plus 16 additional bits of identifying data. The legacy IPv4 address MUST be locally unique within its network segment. A backwards-compatible IPv4+ that uses an RFC1918 address for its legacy IPv4 address SHOULD (MUST?) be connected to a Router or Gateway that is capable of Network Address Translation.&lt;p&gt;

As the protocol gains acceptance, core BGP routes MAY be extended to full /32 networks.&lt;p&gt;

An IPv4+ node learns it is on an IPv4+ compatible network through an extra DHCP option, or it may be statically configured as such.&lt;p&gt;

IPv4+ ARP protocol is not currently defined.&lt;p&gt;

An IPv4+-aware gateway OR node MUST be aware of the mapping from IPv4+ addresses to legacy IPv4 addresses. The mapping SHOULD be programmatic - e.g. 192.168.1.2 corresponds to 72.14.204.99.1.2.&lt;p&gt;

MOST implementations will likely be RFC1918 addresses for legacy IPv4, and routable IPv4 addresses as the first four octets of the IPv4+ address. So-called "Public Hosts" MAY exist at some point in which they have both a routable IPv4 address AND an IPv4+ address. The only purpose of such a host would be future-proofing - no real benefit is conferred, other than ensuring that software stacks can utilize extended addressing.&lt;p&gt;

An IPv4+ gateway MAY define a 'default host' which should receive all unidentified legacy IPv4 traffic, or it may drop any such packets, or it may use a simple heuristic such as 'lowest address wins'.&lt;p&gt;

"IPv4+ ONLY" hosts cannot exist. Non-legacy-routable IPv4+ hosts could exist by the local gateway refusing to NAT addresses by responding with ICMP Destination Unreachable or a new ICMP message.&lt;p&gt;

Software implementations SHOULD embed 48-bit IPv4+ addresses in their existing IPv6 software stacks - which have already been implemented and rolled out. A special segment of IPv6 space SHOULD be allocated and reserved for this embedding to ensure no collisions occur if IPv6 were to become more widespread.&lt;p&gt;

&lt;h2&gt;Interoperability Scenarios&lt;/h2&gt;

&lt;h3&gt;two IPv4+ nodes on the same network&lt;/h3&gt;
MUST use their legacy IPv4 addresses to communicate. An IPv4+ node can identify the IPv4-legacy address that corresponds to the other node because of the nodes required knowledge of mapping between IPv4+ and IPv4-legacy addresses.&lt;p&gt;

&lt;h3&gt;two IPv4+ nodes on different networks with through IPv4+ transit&lt;/h3&gt;
IPv4+ packets are sent and received through extended IPv4+ addresses.&lt;p&gt;

&lt;h3&gt;IPv4 node and IPv4+ node on same network&lt;/h3&gt;
An IPv4+ node will use its IPv4 address and the IPv4 protocols to contact the 'legacy' node. The IPv4+ node can identify the IPv4 node via its legacy 32-bit address.&lt;p&gt;

&lt;h3&gt;IPv4 node and IPv4+ node on different networks, IPv4+ aware router on IPv4+ network&lt;/h3&gt;
The IPv4+ node uses its legacy IPv4 address to talk to the IPv4 node. The IPv4+-aware router NAT's the traffic to the IPv4 node.&lt;p&gt;

&lt;h3&gt;IPv4 node and IPv4+ node on different networks, IPv4-only router on IPv4+ node's network&lt;/h3&gt;

&lt;p&gt;&lt;b&gt;Interesting&lt;/b&gt; - at some point the IPv4+ node MUST become aware that it does not have through connectivity to the other IPv4+ node, and must fall back to using its legacy address. The IPv4 gateway or router will not be able to communicate to the IPv4+ node because the IPv4+ node will 'appear' to be transmitting packets from an incorrect address. The IPv4+ node SHOULD eventually disable IPv4+ connectivity as it will be unable to communicate to any other devices. An ICMP 'Ping' exchange may be employed to determine that the gateway is not IPv4+ aware by examining the return packet's IPv4 options (if any).&lt;p&gt;

&lt;h2&gt;Migration Scheme&lt;/h2&gt;
"Access" routers (small office, home office) need new firmware to handle iPv4+. IP stacks in major operating systems need extensions for IPv4+. ISP's who do not firewall their customers do not need to do anything. IPv4+ compatible applications now have restored end-to-end connectivity.&lt;p&gt;

Eventually, DNS extensions SHOULD be created to permit returning extended IP4+ addresses for services.&lt;p&gt;

An ARP extension MAY be at some point required for nodes that do not require legacy connectivity.&lt;p&gt;

BGP routing will eventually need to be broadened to support /32 extended networks (a /32 network could correspond to a full 65,000 host internetwork).&lt;p&gt;

Interior routing protocols MAY need to be extended to make routing decisions based on extended IPv4+ addresses. The header order and length has been optimized to make this as painless as possible, but it may still be painful.&lt;p&gt;

An additional 8-bits of address space can be reclaimed once all routers are compatible with IPv4+ - the length byte can be counted as an address space indicator, which is 3 for all initial IPv4+ networks, but could be allowed to vary once the entire Internet is switched over to IPv4+.&lt;p&gt;

&lt;h2&gt;Concerns&lt;/h2&gt;
This is a stopgap.&lt;p&gt;
Will routers in the 'wild' strip options they do not understand? Will they ever reorder or muck with options? Do we really have to steal that one byte in the option to say '3'?&lt;p&gt;
Will IPv4 live on forever? Will routers always have to handle all the crazy NAT and other stuff that will be a legacy of 'legacy' IPv4?&lt;p&gt;
Will the only additional 'feature' of this IPv4 thing be better BitTorrent nodes?&lt;p&gt;
&lt;b&gt;BIG CONCERN&lt;/b&gt; will network devices get confused about seeing IP packets with "apparently" identical IPv4 addresses (really extended IPv4+ addresses) and freak out?&lt;p&gt;
10.0.0.0/8 network is too large to map all of its hosts as IPv4+ addresses to use one legacy IPv4 address. It might require a full Class-C allocation of legacy IPv4 addresses to map every possible host. Yuck.&lt;p&gt;
Should this protocol actually attempt to map full IPv&lt;b&gt;6&lt;/b&gt; addresses into appropriate extension headers?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/brady/~4/CsUVSckCCY0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/1696537213344473202/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2011/02/modest-proposal.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1696537213344473202?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1696537213344473202?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/CsUVSckCCY0/modest-proposal.html" title="A Modest Proposal..." /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.uberbrady.com/2011/02/modest-proposal.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUUAQng-cSp7ImA9Wx9bEEg.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-8607107918980779572</id><published>2011-02-18T12:52:00.004-05:00</published><updated>2011-02-18T14:27:23.659-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-02-18T14:27:23.659-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><category scheme="http://www.blogger.com/atom/ns#" term="IPv6" /><title>IPv6</title><content type="html">So, two things about IPv6 - first, a little bit about how to do it if you're all Mac'ed up like me, and then, a little rant.&lt;p&gt;

The &lt;i&gt;easiest&lt;/i&gt; way to get IPv6 working it is to grab a copy of &lt;a href='http://www.deepdarc.com/miredo-osx/'&gt;Miredo for OS X&lt;/a&gt;. This lets your mac, pretty much automagically, get a connection to the IPv6 Internet via an IPv4 tunnel anywhere that you have IPv4 connectivity. It's nearly painless, and at that point, you can start to at least do some basic playing around with IPv6 stuff. I enabled IPv6 on my home network, but I still have Miredo installed but deactivated if for some reason I wanted to use it when I'm at a coffee shop or some other network.&lt;p&gt;

The &lt;i&gt;good&lt;/i&gt; way to do it is to go to &lt;a href='http://tunnelbroker.net'&gt;tunnelbroker.net&lt;/a&gt; and sign up (it's free!). Then configure your Airport Extreme to do tunneling by following &lt;a href='http://www.tunnelbroker.net/forums/index.php?topic=680.msg7440#msg7440'&gt;these&lt;/a&gt; directions. Voila. Now you have IPv6 connectivity to the intarwebs...or the ip6ernet. Whatever.&lt;p&gt;

The &lt;i&gt;best&lt;/i&gt; way to do it - and I haven't done it this way - is to actually get IPv6 connectivity from your ISP - no tunneling or anything, just native connectivity. I can't do this because Time Warner doesn't give me that, or maybe my Airport isn't so good at doing that. I don't really know.&lt;p&gt;

So far, the one thing I can see here is that you &lt;b&gt;could&lt;/b&gt; begin to use this IPv6 connectivity to work around the general destruction of the internet any-to-any principle - the idea that any IP address on the internet should be able to contact any other. This is basically no longer the case, as many people use RFC1918 addresses behind NAT to conserve IP addresses (and also there are some positive security implications). So my computer at 10.0.1.2 can't necessarily talk directly to your computer at 192.168.1.2 (or, even worse, your computer at 10.0.1.2 but behind your NAT, and not mine). The way we work around this type of things is all kinds of magical firewall port-mapping and other such things. It's a pain in the butt. Services like AIM's ability to send files, or various screensharing utilities all now require some kind of centralized server that everyone can connect to because just about every network-connected computer tends to be behind a NAT. That centralization is unfortunate, and a drain on services that really should just be about connecting anyone to anyone.&lt;p&gt;

But if you have IPv6 set up in the 'good' way listed above (or 'better'), you actually have a new option. You can un-check "block incoming IPv6 connections" on your Airport, and now have access to &lt;b&gt;anything&lt;/b&gt; in your network that speaks IPv6 from the outside world (again, so long as the outside world is IPv6). Of course, big security implications here, but that &lt;b&gt;could&lt;/b&gt; actually be a way of making IPv6 somewhat (remotely) useful. Things that like this type of connectivity might be: BitTorrent-esque things...peer-to-peer video applications...some kinda of home-hosting things...I dunno. That type of stuff. But, in short, while at Starbucks, I could fire up my Miredo-for-OS X client, and connect to various things in my home. That could be useful for some people.&lt;p&gt;

My experience with this new setup is rather underwhelming. I can go to &lt;a href="http://ipv6.google.com"&gt;ipv6.google.com&lt;/a&gt;. I guess on &lt;a href='http://isoc.org/wp/worldipv6day/'&gt;World IPv6 day&lt;/a&gt; I'll be able to...somehow...enjoy some festivities or something. I don't really have any home servers nowadays.&lt;p&gt;

&amp;lt;Begin Rant&amp;gt;&lt;p&gt;
Who the fuck came up with this stupid-ass migration plan? It has to be one of the dumbest things I have ever seen. IPv6 the protocol is OK (at best)...it really feels pretty close to IPv4, except with a bigger address space. OK, I guess. DJB (who is brilliant, but I think may be batshit insane) &lt;a href='http://cr.yp.to/djbdns/ipv6mess.html'&gt;sums up the problem really well.&lt;/a&gt;&lt;p&gt;

In short, there's negligible benefit for going to IPv6. You can't really get anywhere you couldn't get to anyways. If IPv6 had been designed to interoperate with IPv4, we would be far closer to being in a happy IPv6 world - think about how many machines are dual-stacked right now? Those machines would instead be &lt;b&gt;single&lt;/b&gt;-stacked, and some early adopters, or price conscious people (think: Web startup types who like to skip vowels in their domain names) might be able to start offering IPv6 only services, and would be able to start hitting users right now. But, no. The migration scheme seems to be:
&lt;ol&gt;
&lt;li&gt;Migrate everyone and everything to IPv6 now&lt;/li&gt;
&lt;/ol&gt;
And you're done! Isn't that easy? The standard has been out for a bajillion years. The IPv4 shortage has been a problem for a bajillion years. And we're still here. Not because the protocol for IPv6 is flawed, but because there's no migration scheme at all. There's no backwards compatibility. This whole infrastructure has to layer over the entire internet. Who the hell thought this was a good idea? I mean, sure, it's "simpler", protocol-wise, to do that...but a few more years of protocol engineering &lt;b&gt;instead&lt;/b&gt; and a true backwards-compatible solution and we would've had people switching ages ago. Go &lt;a href='http://en.wikipedia.org/wiki/IPv6_transition_mechanisms'&gt;look&lt;/a&gt; at how many transition mechanisms are in place for IPv4-to-IPv6. It's stupid. That alone indicates the level of FAIL that is likely here.&lt;p&gt;
The other problem I have with IPv6 has to do with routing tables. And protocol stacks. Right now, to do any non-trivial amount of TCP/IP networking (let's imagine HTTP for this example), you need:

&lt;ul&gt;
&lt;li&gt;DNS&lt;/li&gt;
&lt;li&gt;some kind of routing protocol has to be working right&lt;/li&gt;
&lt;li&gt;ARP to figure out how to get to your local endpoint&lt;/li&gt;
&lt;li&gt;DHCP to figure out what your IP address is going to be&lt;/li&gt;
&lt;/ul&gt;

Network troubleshooting ends up being an interesting and non-trivial problem of figuring out who can ping who (whom? Grammar fail. Sorry), what routing tables look like on various intermediate devices, what IP address you get from DNS, is your DNS server working, etc, etc. It's a muddle, but it's a muddle that's been treating us well on this whacky internet of ours.&lt;p&gt;

However, in the IPv6 world, we now have - the entire protocol stack for IPv4, PLUS a protocol stack for IPv6, &lt;b&gt;and&lt;/b&gt; a crazy autotunneling doodad with a weird anycast IPv4 address (oh, that'll be fun). And a routing table that is exploding out of control. I mean, my dinky little home network (theoretically) gets a /64 network. If every Time Warner customer gets a /64 - and there's not some means of aggregating routes together - the routing table completely goes insane. Now I'd assume that TW would aggregate its customers into a /48 or something - god, I hope so! But still, we're talking about a world where there are networks all over the place.&lt;p&gt;

There's a big question as to whether or not people ought to get provider-independent network addresses or not. I think I know the answer to this: No, they should not. It's suicide. I think the real solution for this is at the DNS level - you should get addresses that correspond to your rough physical place on the internet to keep the routing tables somewhat simple, and if you want to move endpoints around, you change DNS entries. Get away from thinking of IP's as static. If DNS were baked deeper into the protocol stack, this could work extremely well. Want to have a webserver at www.whatever.com? If you have some kind of authorization, your webserver would come up and use some kind of key exchange to somehow tell DNS that it is www.whatever.com. If you move, you just move your webserver. Your keys still work. If you set up a webserver in your house - same thing. Anyways, that's just hand-waving. There still would have to be some way of bootstrapping that (like, what IP address do I contact the webserver at? Maybe you find that out by talking to your local gateway? Dunno)&lt;p&gt;
&amp;lt;End Rant&amp;gt;&lt;p&gt;

I guess that 1) wasn't a little rant and 2) was a little rambly. So sue me.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/tLO7ov6OAY4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/8607107918980779572/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2011/02/ipv6.html#comment-form" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/8607107918980779572?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/8607107918980779572?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/tLO7ov6OAY4/ipv6.html" title="IPv6" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>6</thr:total><feedburner:origLink>http://www.uberbrady.com/2011/02/ipv6.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A04CRng_eip7ImA9Wx5bEkQ.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-6201945350637552758</id><published>2010-10-28T16:57:00.003-04:00</published><updated>2010-10-28T17:06:07.642-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-28T17:06:07.642-04:00</app:edited><title>ucspi-tcp and stupid errno.h (CentOS and ucspi-tcp)</title><content type="html">I keep running into this and doing my standard google-up-the-answer-routine didn't seem to be working.&lt;p&gt;

In short, ucspi-tcp doesn't compile on CentOS boxes (or RedHat boxes). Cuz DJB doesn't "believe in" RedHat's "you must have an errno.h" thing. Hey, I love DJB, and his software, but I also think he's impractical and a nutjob sometimes. This would be one of those times.&lt;p&gt;

Lots of folks had patch-related ways of fixing the problem, I thought those seemed rather laborious. I just stole The Internet's method for another DJB package.&lt;p&gt;

Just append -include /usr/include/errno.h at the end of the first line of conf-cc so it looks like this:&lt;p&gt;
&lt;blockquote&gt;
&lt;tt&gt;gcc -O2 -include /usr/include/errno.h

This will be used to compile .c files.
&lt;/tt&gt;
&lt;/blockquote&gt;

Boom, everything works now.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/cvL8ctwLqrQ" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/6201945350637552758/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/10/ucspi-tcp-and-stupid-errnoh-centos-and.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6201945350637552758?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6201945350637552758?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/cvL8ctwLqrQ/ucspi-tcp-and-stupid-errnoh-centos-and.html" title="ucspi-tcp and stupid errno.h (CentOS and ucspi-tcp)" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/10/ucspi-tcp-and-stupid-errnoh-centos-and.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkAHRn4_eip7ImA9Wx5UF0Q.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-5380918876650191387</id><published>2010-10-22T21:36:00.003-04:00</published><updated>2010-10-22T21:52:17.042-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-22T21:52:17.042-04:00</app:edited><title>Even Mo' Math...</title><content type="html">So &lt;a href='http://beckleyworks.com'&gt;Beckley&lt;/a&gt; got a hold of the &lt;a href='http://metrocardmath.com'&gt;MetroCard Math&lt;/a&gt; site and built on top of &lt;a href='http://ddominguez.us'&gt;David's&lt;/a&gt; fantastic work to build even more prettiness, neat-workingness, and general niftitude into the site.&lt;p&gt;
We also put in a thingee - well, by 'we' I mean 'he' - he put in a thingee that lets you see how the new price changes will affect you. For me, I definitely will be sticking with the pay-per-ride.&lt;p&gt;
And another thing - I actually tested the new (divisible-by-a-nickel) magic number, and it *does* work. My MetroCard has an exactly even number of rides on it. Cool. Now I just have to do something with all these MetroCards that have 10 or 20 cents on them - perhaps a new part of the site that lets you put in how much money is on your cards, and then it tells you how much more to put on to get it 'even'? Not a bad idea...&lt;p&gt;
Gory Details: so, talk to any computer sciencey person and they will always tell you that Floating Point Math is Hard. I have only rarely run into this, but the rounding algorithms are very specific when you buy stuff, and if you're off by a penny, then, well, you're off by a penny, and things stop working. We found a couple of minor (off-by-one) bugs here and there, and every time it seems like I fixed one, the rest of the results would start to go haywire. The real problem is that I am trying to 'move' the rounding around the formula:&lt;p&gt;
&lt;blockquote&gt;round_for_money($x * 1.15) = n * $2.25&lt;/blockquote&gt;
Now solve for 'x', and let 'n' be any integer - well, that pesky 'round()' is in the way, and if you just try to move it to the other side, or round at some random and/or inopportune time, then when you get back to the original equation, sometimes the numbers don't work out anymore. It sucks.&lt;p&gt;
So I racked and racked my brain trying to figure out a way to do my simple solve-for-x routine. I really just want to try different integers for 'n' until I find an answer that's "acceptable." But that doesn't work. At all. Or at least, I don't know what mathematical operation I can do to move that round() function off the left side so I can try to have a formula that points to 'x'.&lt;p&gt;
What did I do finally? I gave up. I left the formula as it is above, and just run 'x' from 0 to "a lot" (a thousand bucks or a hundred bucks I think?). The answer I get is going to be completely accurate, but it wastes computing power. Well, too bad, your browser has to do a little bit of multiplication in a loop. My condolences. But! The result is, I'm pretty convinced my answers are to-the-penny accurate now. We'll see when the big price change kicks in.&lt;p&gt;
Thanks again to &lt;a href='http://ddominguez.com'&gt;David Dominguez&lt;/a&gt; for the initial switch to jQuery-powered MetroCard Math, and thanks to &lt;a href='http://beckleyworks.com'&gt;Beckley&lt;/a&gt; for the full re-skinning he pulled off.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/Bq8Wh2lDkNM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/5380918876650191387/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/10/even-mo-math.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/5380918876650191387?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/5380918876650191387?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/Bq8Wh2lDkNM/even-mo-math.html" title="Even Mo' Math..." /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/10/even-mo-math.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkcCRXg6eCp7ImA9Wx5UEUs.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-1817465799003052288</id><published>2010-10-15T11:59:00.002-04:00</published><updated>2010-10-15T12:27:44.610-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-10-15T12:27:44.610-04:00</app:edited><title>More Metrocard Math...</title><content type="html">So I've updated my &lt;a href='http://metrocardmath.com'&gt;Metrocard Math&lt;/a&gt; site.&lt;p&gt;

First, my friend &lt;a href='http://ddominguez.us'&gt;David Dominguez&lt;/a&gt; helped out to make it much, much prettier. He also added some jQuery magic, and changed up a significant amount of how the site is structured. I was trying a weird idea - where I would strip the markup down to its most basic elements, and style it from there using cleverly-constructed css selectors, but I don't think it worked out. My friend &lt;a href='http://blog.deadkarma.com/'&gt;Bryan&lt;/a&gt; tried to restyle it as well, and the rigidity of the markup basically stopped him in his tracks. So, anyways, now it looks prettier and is definitely more usable on my phone.&lt;p&gt;

I also had tried to buy a metrocard for one of the Magic Number amounts the other day at a vending machine, and it was rejected due to "invalid amount." Stupid. It had worked before. I tried the small number. I tried the big number. Nothing worked. On a hunch, I tried $11.75 instead of $11.74. Success. And of course, I will eventually have a metrocard with a penny on it. So apparently, the number has to be divisible by 5? So I've added that to the site, and we'll see when I next buy a metrocard if the new system actually works. I hope they don't make it where it has to be divisible by $0.25, that would really sting.&lt;p&gt;

I still want to do something where you can toggle between the current prices and the newly announced ones. But right now you can just type in the new numbers - Here's what they are according to the &lt;a href='http://www.zwire.com/site/news.cfm?newsid=20449001&amp;BRD=2731&amp;PAG=461&amp;dept_id=574902&amp;rfi=6'&gt;Queens Chronicle&lt;/a&gt; (which I used to consult for a million years ago!) $104 is the new 30-day, $2.50 is the new single ride, and $29 is the new 7-day. The one-day funpass is going to be eliminated and so will the 14-day unlimited. Oh, and I hadn't seen this before - there's now going to be a $1 surcharge every time you pick up a new metrocard (though that doesn't start till some time in 2011) OUCH. That means when you leave your metrocard at home and have to buy another one it's *really* going to sting. One more extra buck. Damn. I mean, you can still use the lastest magic number ($15.65 I believe? Though I worry my rounding might not match the MTA's...), but you definitely will not want to be throwing out your metrocards anymore.&lt;img src="http://feeds.feedburner.com/~r/brady/~4/zvALcRVMHnA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/1817465799003052288/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/10/more-metrocard-math.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1817465799003052288?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1817465799003052288?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/zvALcRVMHnA/more-metrocard-math.html" title="More Metrocard Math..." /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/10/more-metrocard-math.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkQHQH0-eSp7ImA9Wx5WFEg.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-5090051245102249604</id><published>2010-09-25T18:25:00.003-04:00</published><updated>2010-09-25T18:38:51.351-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-25T18:38:51.351-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="mta" /><category scheme="http://www.blogger.com/atom/ns#" term="metrocard" /><title>Metrocards and Math</title><content type="html">I work from home, mostly, so I don't usually need an unlimited metrocard. Every time the MTA changes the prices on evertyhing I have to go through and write another stupid spreadsheet to figure out what costs what. And I &lt;b&gt;hate&lt;/b&gt; the fact that when you buy a 10$ or 20$ or 8$ metrocard, you get a number of rides and some stupid amount of money left over. I was actually juggling 5 different metrocards a few weeks back, each with slightly different amounts on them. Just stupid.&lt;p&gt;

So I finally gave in and made a &lt;a href='http://metrocardmath.com'&gt;Web site about Metrocard Math.&lt;/a&gt; It has a thing where you can experiment with what-if scenarios about fare hikes and stuff (it's kinda like a javascript spreadsheet). The interesting thing I found was this: $9.78. Buy a metrocard for that much and you will have exactly 5 rides, with no money left over. Of course, if you're buying your metrocard via Credit Card, they won't let you use an amount less than 10$, so you have to use the next magic number: $11.74.&lt;p&gt;

I was thinking I might put in something about the proposed 'cap' that the MTA is talking about doing for their unlimiteds, I just don't know what to do with it. I guess "maximal theoretical value" I can do? Or you can just look at the number and compare to 'rides needed to beat pay-per-ride'...&lt;p&gt;

As an aside, the site looks like absolute shit. I still am the worst web designer in the known universe. But I don't mind much, the only thing I do mind is that it is hard to read on an iPhone. And that's usually when I want the damned site - when I'm trying to get on the N train, my metrocard has run out, and I forgot the Magic Number. Anyways, I experimented with keeping the presentation, content, and behavior all separate (and yet all inline on the page). If I ever get to styling it, it'll be interesting to see how I can do that. For instance, especially on the iPhone, the disabled fields don't look very different from the enabled ones. I don't remember if in CSS3 though you can specify a style of a disabled field - but I would have to imagine that you can, right? Well, when I next feel like poking at it, maybe if I add in 'swipe-cap' support like the MTA is proposing, I might try and throw some iphone-specific styling on there to make it useful for me (the only time I actually use it, in fact).&lt;img src="http://feeds.feedburner.com/~r/brady/~4/ZXDef63HPRE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/5090051245102249604/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/09/metrocards-and-math.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/5090051245102249604?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/5090051245102249604?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/ZXDef63HPRE/metrocards-and-math.html" title="Metrocards and Math" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/09/metrocards-and-math.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEEHQnY6eyp7ImA9Wx5QGU8.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-8604261421759632828</id><published>2010-09-08T01:30:00.003-04:00</published><updated>2010-09-08T02:17:13.813-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-08T02:17:13.813-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="web 2.0" /><category scheme="http://www.blogger.com/atom/ns#" term="Blogger" /><category scheme="http://www.blogger.com/atom/ns#" term="Tumblr" /><category scheme="http://www.blogger.com/atom/ns#" term="LightDesktop" /><title>Blogspot and Tumblr</title><content type="html">&lt;p&gt;Well, for those of you sick of hearing the trivial minutiae about how nifty &lt;a href='http://lightdesktop.com'&gt;LightDesktop&lt;/a&gt; is, never fear! Your prayers have been answered. I made a &lt;a href='http://lightdesktop.tumblr.com'&gt;Tumblr Blog thingee just for LightDesktop stuff&lt;/a&gt;, so I can yammer on endlessly about file system optimizations and other such crap.&lt;/p&gt;
&lt;p&gt;So now when I talk about LD here - it will hopefully be coming from a more personal perspective. In that vein, a few things to mention - one is that LightDesktop got &lt;a href='http://distrowatch.com/weekly.php?issue=20100906#waiting'&gt;mentioned&lt;/a&gt; on &lt;a href='http://distrowatch.com'&gt;DistroWatch&lt;/a&gt;. It was just a little teensy one-sentence blurb, but I wasn't quite ready for this. Whoops! I &lt;b&gt;did&lt;/b&gt; send an email to the distrowatch people saying, "Hey guys, probably a bit early to mention me anywhere on your site or anything, but just wanted to let you know I'm around..." and I expected they might ask me a question, send some generic message that was like, "Hey, sounds good, good luck, let us know when you're ready" or anything like that.&lt;/p&gt;
&lt;p&gt;And I was troubleshooting something the next day or two and tailing the server logs...strangely enough I kept finding new people hitting the informational web site. I looked into the referer tags, and lo and behold, they're clicking over from the DW article. Awesome!&lt;/p&gt;
&lt;p&gt;So I went from getting one hit a day, up to 60, up to 800 the next day. So I've had to go run around and make sure my Google Analytics tags and such are working, and I realized the worst thing - actual downloads weren't being tracked at all. So I had to build a little downloader script so I could track that, too. Hopefully, I got it. We'll see.&lt;/p&gt;
&lt;p&gt;And there have been a couple of little tiny things I wanted to mention here or there about LD, but I felt like I might be spamming to put them here. So, the Tumblr thing. First off, I have to say - man, coming back here to Blogger feels like going back in time 10 years. &lt;a href='http://tumblr.com'&gt;Tumblr&lt;/a&gt; has their shit together. It has nice, big pretty fields, beautiful stuff everywhere, insanely easy. It feels a little sluggish here and there, and &lt;b&gt;feels&lt;/b&gt; all railsey all over the place - even though it may or may not be built on that. So I pop back in here to my old Blogger thing to check out what's up - and wow. It &lt;b&gt;feels&lt;/b&gt; old.&lt;/p&gt;
&lt;p&gt;So within half an hour of setting up on Tumblr, I found a theme just makes me happy every time I look at it. Gotta have it. Knocks it out of the park (well, for me). Gotta get comments going, so I'm signing up for a &lt;a href='http://disqus.com'&gt;Disqus&lt;/a&gt; account and trying to hook that in. Generally it's working pretty well. One thing I didn't like was when you look at a list of posts, it didn't show anything about comments - and I wanted a comment-count to be listed there - I'm hoping to have people comment all the time. So now I have to customize my theme. And I've gotta say, not all that hard. A little poking around, a little documentation, and I'm done.&lt;/p&gt;
&lt;p&gt;I can definitely say that if I were starting up a new Blog or whatever, I would, 100%, do it on Tumblr. This Blogger thing has been pretty good to me, but it's definitely got its problems. And they've been the same problems for years and years and years. If I could find a nice way of exporting/importing articles...who knows, I might do it?&lt;/p&gt;
&lt;p&gt;Food. I have made a really concerted effort to make sure to eat my full three meals a day today - I've been busy lately so I've been skipping quite a few meals. And I'm embarassed at the improvement to my mood and my energy levels from this relatively simple source. I've been plowing &lt;b&gt;through&lt;/b&gt; feeling hungry, and smashing &lt;b&gt;over&lt;/b&gt; actually feeling down and slightly depressed from not having eaten enough. Man, if I just ate normally, imagine what I could accomplish? I'm going to make a real concerted effort.&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/brady/~4/eX3ivmYf0ns" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/8604261421759632828/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/09/blogspot-and-tumblr.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/8604261421759632828?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/8604261421759632828?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/eX3ivmYf0ns/blogspot-and-tumblr.html" title="Blogspot and Tumblr" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/09/blogspot-and-tumblr.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkIMSX89fyp7ImA9Wx5QF0k.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-6487037850263144171</id><published>2010-09-05T23:26:00.002-04:00</published><updated>2010-09-05T23:43:08.167-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-05T23:43:08.167-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="AIM" /><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="LightDesktop" /><title>Lightdesktop now self-hosting (ish!)</title><content type="html">So my nifty LightDesktop project has (almost, kinda, sorta) hit a new milestone - I'm writing you this blog post from it right now!&lt;p&gt;

I have officially transferred all the development files into the filesystem (in Rackspace Cloud Files), and should be able to develop it...from it. I will be getting a 'dev' version vs. a 'prod' version distinction going so I don't destroy the filesystem for everyone when I botch something (usually the CREST-fs filesystem) and post it up. Considering my development environment is it, itself - that makes sense.&lt;p&gt;

So no more CentOS box (or VM, actually) for a while. And, man, does dogfooding pop all kinds of bugs that I want fixed ASAP. Window management is pretty horrible.&lt;p&gt;

I am REALLY impressed with the browser. It has been able to handle nasty Javascript-heavy sites with relative ease. AOL - not usually a company I associate with doing things right - has some kind of insane Web 2.0 AIM client hooked in to their webmail that works suprisingly well. I'm shocked they made it so well, and even more shocked that it runs in my slightly janky browser. But that's all due to the WebKit people, and, indirectly at least, Apple.&lt;p&gt;

One thing that I've really enjoyed is how lightning-quick everything is. When you make something as super minimalistic as this thing is, there's not a lot of stuff going on to slow things down. I have done enough testing (though not quite 'living') in the new system that when I get back to using my Mac normally, it feels sluggish. And that thing has 4 gigs of RAM and a core 2 duo and whatnot! This thing has - crap, I don't even know (poking through /proc...)...a 2.2GHz Celeron, single core. 2 Gigs of RAM though. And I bought it at Best Buy for $300 or $400 dollars! They of course didn't want to sell it to me - I had to go to a second Best Buy to find one where they would. Must've been set up as a bait-n-switch or something. Or maybe they were legitimately out of stock, who knows.&lt;p&gt;

Oh, another fun anecdote - I have Windows (Vista, ugh) installed on here too. And at one point I inadvertently let it reboot into Windows. I figured, well, let me grab all my software updates and stuff....nope! Didn't work. The wireless had mysteriously stopped working for no discernable reason. I wondered if the hardware was broken. Rebooted into Lightdesktop, and the wireless came right up. Love it!&lt;img src="http://feeds.feedburner.com/~r/brady/~4/GucsX63cFxM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/6487037850263144171/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/09/lightdesktop-now-self-hosting-ish.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6487037850263144171?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6487037850263144171?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/GucsX63cFxM/lightdesktop-now-self-hosting-ish.html" title="Lightdesktop now self-hosting (ish!)" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/09/lightdesktop-now-self-hosting-ish.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcER3o9fyp7ImA9Wx5QFUo.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-6341576094250250320</id><published>2010-09-03T17:49:00.005-04:00</published><updated>2010-09-04T01:26:46.467-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-09-04T01:26:46.467-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="LightDesktop" /><title>A new LightDesktop Release</title><content type="html">&lt;p&gt;So my evil ploy of tricking myself into playing with LightDesktop a few weeks back worked like magic. I've been hard at work since then and I think I've got some good stuff -&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Lots of optimization work in the CREST-fs filesystem. It's getting faster and faster. It's still much slower than a raw hard drive though, but there are quite a few optimizations yet to be done.&lt;/li&gt;
&lt;li&gt;New &lt;a href='http://account.lightdesktop.com/newuser.php'&gt;Signup&lt;/a&gt; and Server side architecture (based on Rackspace Cloud and Cloud Files. Infinite Storage! So awesome.)&lt;/li&gt;
&lt;li&gt;A GUI logger-inner-thing. Feels more 'pro' to me, for some reason.&lt;/li&gt;
&lt;li&gt;I've yanked the old DAV-fs fallback - it just sucked too much, and made things complicated. And I like things uncomplicated. If someone were dying for this I could put it back. I think 99.999% of the users of this thing will use the server-based storage.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;Numbers:&lt;/h3&gt;
&lt;p&gt;The system, when full installed, boots in &lt;b&gt;15 seconds&lt;/b&gt; on my eeePC. No joke. &lt;/p&gt;
&lt;p&gt;The install CD is around &lt;b&gt;26MB&lt;/b&gt; in size.&lt;/p&gt;
&lt;p&gt;As a test, I timed myself doing a real-world install - I downloaded the ISO, created a VM in virtualBox, had it boot up, logged in as me - and had my files sitting in my home directory in &lt;b&gt;3 minutes 48.5 seconds.&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;Again, the premise here is: all your data lives in the cloud, the OS does too (or is hosted from it) so you get automatic updates and everything. There's no such thing as 'installing' an application, you should just be able to use one. It's alpha, blah blah blah, will delete your data, will destroy your computers, drink your beer, and insult your mother. Caveat Download-or.&lt;/p&gt;
&lt;h3&gt;The Files&lt;/h3&gt;
&lt;a href='http://lightdesktop.com/LightDesktop.iso'&gt;CDROM ISO&lt;/a&gt;&lt;br&gt;
&lt;a href='http://lightdesktop.com/lightdesktop.fat'&gt;USB disk image&lt;/a&gt;&lt;img src="http://feeds.feedburner.com/~r/brady/~4/CNtF5Obl6lI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/6341576094250250320/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/09/new-lightdesktop-release.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6341576094250250320?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6341576094250250320?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/CNtF5Obl6lI/new-lightdesktop-release.html" title="A new LightDesktop Release" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/09/new-lightdesktop-release.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQBRXo_eSp7ImA9Wx5SFkg.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-3084592771219775407</id><published>2010-08-12T18:25:00.003-04:00</published><updated>2010-08-12T18:32:34.441-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-08-12T18:32:34.441-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="linux" /><category scheme="http://www.blogger.com/atom/ns#" term="LightDesktop" /><title>How long to install your OS?</title><content type="html">So I was thinking that I wanted to play with something on Ubuntu yesterday. I wasn't sure that I necessarily wanted OpenOffice and all kinds of other crap that just come with a standard distro/download, so I went for a minimalist install, and figured I could just grab the various little bits that I needed to upgrade the system to a point where it did what I needed.&lt;p&gt;

I spent about an hour and change (including download time) getting it to work, and it never really did what I wanted it to. Kinda disappointing. But what I thought was strange was how looooong everything took. I mean, literally, we're talking like 60, 90 minutes? That's serious.&lt;p&gt;

So out of curiousity today, and as a deliberate way of easing my way back into lightdesktop development, to bench how long it would take to download and install LightDesktop onto a VirtualBox VM.&lt;p&gt;

My timing included creating the VM, and downloading the image to work from.&lt;p&gt;

&lt;b&gt;3 minutes 48.5 seconds.&lt;/b&gt;&lt;p&gt;

That's getting from &lt;i&gt;nothing&lt;/i&gt; to &lt;i&gt;having my crap sitting in the home directory&lt;/i&gt; in less than 4 minutes.&lt;p&gt;

Damn! I gotta get back into this stuff. I like it when it works.&lt;p&gt;&lt;img src="http://feeds.feedburner.com/~r/brady/~4/dPkviMG07A8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/3084592771219775407/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/08/how-long-to-install-your-os.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/3084592771219775407?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/3084592771219775407?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/dPkviMG07A8/how-long-to-install-your-os.html" title="How long to install your OS?" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/08/how-long-to-install-your-os.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUAMRn8zfCp7ImA9WxFbEE8.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-4028736604294805689</id><published>2010-07-01T16:43:00.003-04:00</published><updated>2010-07-01T18:36:27.184-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-01T18:36:27.184-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Time Warner" /><category scheme="http://www.blogger.com/atom/ns#" term="Rant" /><title>Time Warner is a bunch of poopfaces, especially "DP Loss Prevention"</title><content type="html">So this is one of those blog posts where I rant and whine and complain about how some service provider done me wrong. If you dislike those posts, feel free to wait for the next one. This one will come off as extremely whiny. You have been warned.&lt;p&gt;

Fucking Time Warner. You assholes. Especially Dawn, from DP Loss Prevention. I hate you. You suck.&lt;p&gt;

So, I work for &lt;a href='http://bespincorp.com'&gt;me&lt;/a&gt;. I need internet to do what I do. I just moved to Astoria from my old place in Jamaica. So I cancelled my old cable internet service, turned in the modem thingee. Like a good little boy. They asked for no money from me, and said I could call them and they would tell me if I owed them anything. Fine. I of course immediately disregarded that advice - if I owed them something they'd tell me and I'd pay it. I'm not chasing them down to ask them how much I owe.&lt;p&gt;

So after a week and a half of no internet, Time Warner finally shows up to install it on a Friday. Guy is nice, jams it right out in no time. Even knew his way around a Mac, had me go into the Advanced tab thing to do "renew DHCP lease" - I didn't know that was there! Up and running. Fast, low-latency, happy times.&lt;p&gt;

So, I'm literally sitting on the toilet end of day Friday, and my phone rings. I consider it rude to talk whilst I am...in such a situation, so I decline to answer. Time is now 5:31pm. I finish my business. I go listen to my voicemail. "&amp;lt;&amp;lt;remnants of talk with co-worker&amp;gt;&amp;gt;Hi &amp;lt;&amp;lt;mispronunciation of my first name&amp;gt;&amp;gt;...Uhm....&amp;lt;&amp;lt;horrific mispronunciation of my last name&amp;gt;&amp;gt;, this is Dawn from Time Warner. Please give us a call back regarding your account. 718-888-4393". Fine. I'm an upstanding citizen, maybe I owed them something from where I was living before? Better give a call back. I do. Generic-sounding voicemail for "DP Loss Prevention" in a computerized voice. Oh well, if it's important they'll call me back. I ain't leavin' no message for some weird generic voicemail box at a random 718 number.&lt;p&gt;

Saturday morning rolls around and I flip on the iPad. No internet. Hrm. Maybe a remnant from the install? Power-cycle my modem. No internet. Okay, time to call tech support. I call. The automated system picks up my phone number and says "it seems your account has been disconnected. I'll forward you to a representative." The rep is nice, and says I need to talk to the 718 number that was left on my phone before. Crap. I guess I better. I call back and leave a message with my phone number and explaining that if I indeed owe anything, I'd be happy to pay it.&lt;p&gt;

Nothing happens. I call the main tech support number - they again explain that I need to talk to that one department. I explain that I'd love to - and pay them anything they want - but no one's there. I discover they only work regular business days, and I'm screwed till Monday. Awesome.&lt;p&gt;

Monday rolls in and out. Nothing changes. I call them again, I beg to pay them.  I call DP Loss prevention and leave another message. Note that I am restraining myself from freaking the fuck out on the voicemail because I want them to fix it.&lt;p&gt;

Tuesday. Nothing. I call, another voicemail left to the generic voicemail box. I call tech support, a 'message passed to the supervisor'. I ask to speak to a supervisor, I'm told I will get a call back. At this point, I am freaking out. Did I leave my phone number correctly? Is my phone broken? Do I keep missing the call? What's happening? I go onto a forum and ask for help, they say that there will be an escalation if nothing happens. Great. In the meanwhile, at &lt;b&gt;NO POINT WHATSOEVER&lt;/b&gt; has &lt;b&gt;ANYONE&lt;/b&gt; told me what the hell is going on. I &lt;b&gt;guessed&lt;/b&gt; I must have owed them money - and it must have been quite a bit.&lt;p&gt;

At 4:01pm Tuesday a familiar 718 number shows up on my phone, and behind that number is a familiar voice. My old friend, Dawn. "I understand you want to make a payment?" she asks. You shithead. I answered, "well, assuming that's why you turned me off, if I do owe you money, yes." I'm prepared to shell out $300 on the spot. I need my internet. Must have it.&lt;p&gt;

The bombshell hits. "You owe..........$32.17." I couldn't help myself, I laughed. Relayed my credit card info, and my internet came up after a quick power-cycle of the modem. Unbelievable. Time Warner put me through all of this hell - well, to me it was hell - for thirty bucks. You fucking dickweeds.&lt;p&gt;

So of course during this whole debacle I've been looking at alternatives, and those alternatives made Time Warner's behavior completely obvious - there are none. I can pay roughly the same amount to have 1/10 the bandwidth within 2-3 weeks from Verizon? No good. I was surviving, only barely, using 3G service and that was definitely not going to be a long-term way for me to get by. RCN didn't service my area. There was nothing I could do.&lt;p&gt;

And my feeling of powerlessness might be some of the reason I wigged out so badly - I thought long and hard about telling Time Warner that, no, I'm not going to pay you anything, you pissed me off, and I want to cancel, I'm not paying anything at all. But I couldn't - I'm stuck, needed the connection. I had all kinds of wonderful imaginary conversations, escalating until I could talk to someone's supervisor, getting Dawn fired and permanently making changes to Time Warner's policies...getting them to comp me all kinds of things, making a big stink. I can't though. There's one place I can get a usable connection from, and they are it. So I made a decision, a very very difficult one, to accept the treatment and just get the connection working.&lt;p&gt;

So, in summary, this is what happened. Time Warner called me end of day Friday, left a botched and meaningless message, turned off my service late Friday night (probably early Saturday Morning), never told me why, wasn't even around to turn it on for the next two days, and kept me down for 4 days total....over $30.&lt;p&gt;

I will be happy, happy, happy to get rid of them, as soon as anything even remotely good gets available. I can easily guess what Time Warner's thinking was when they created this group or department or whatever - "Hey, we lost $x in people moving - I want that to be &amp;lt;less than x&amp;gt;! Let's empower this raging horrible monster woman, Dawn, and put her in a department of Pure Evil to torture our own clients!" And $x goes to less-than-x. I hate them so much I'd be happy to pay twice as much for half the service. If they had any competition at all, they would not ever dare. Is that worth $30, Time Warner? I think not.&lt;p&gt;

OK. End rant. Feel much better now. Sorry about that.&lt;p&gt;&lt;img src="http://feeds.feedburner.com/~r/brady/~4/VcW9i2gEyuE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/4028736604294805689/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/07/time-warner-is-bunch-of-poopfaces.html#comment-form" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/4028736604294805689?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/4028736604294805689?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/VcW9i2gEyuE/time-warner-is-bunch-of-poopfaces.html" title="Time Warner is a bunch of poopfaces, especially &quot;DP Loss Prevention&quot;" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/07/time-warner-is-bunch-of-poopfaces.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0IASHs9eip7ImA9WxFQEUQ.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-991999351889889559</id><published>2010-05-06T19:06:00.003-04:00</published><updated>2010-05-06T20:19:09.562-04:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-05-06T20:19:09.562-04:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="iPad" /><category scheme="http://www.blogger.com/atom/ns#" term="apple" /><title>iPad</title><content type="html">My fast review:


&lt;ul&gt;
&lt;li&gt;The screen is MASSIVE. 1024x768, but feels even larger. Because you tend to hold it naturally closer to your face. It feels completely huge, and like it extends into your peripheral vision. It feels more expansive than my MacBook Pro display, and that is 1440x900.&lt;/li&gt;
&lt;li&gt;It is FAST as SHIT. Crap. Damn. Wow.&lt;/li&gt;
&lt;li&gt;A lot of the apps you have are no longer necessary. For example, Facebook. Not needed any more. Just use the full website, it's fine!&lt;/li&gt;
&lt;li&gt;It's heavier than I expected. That's a little problematic when you need to hold it up the same way you hold a book. It's heavier than a book.&lt;/li&gt;
&lt;li&gt;Synchronization is a bitch. Do I have that note on my iphone, ipad, or my MacBook? Or is it synced? This really really sucks.&lt;/li&gt;
&lt;li&gt;How do I carry this thing? If I have to carry my laptop bag, I'll have my laptop. This is totally unanswered and makes it hard for me to figure out how to integrate this into my life. So far, I carry both. This is a shitty solution. And although I'm very comfortable with my sexuality, I don't think I can swing carrying a man-bag.&lt;/li&gt;
&lt;li&gt;It's much, much better for cuddling up on the couch or on the bed. I think I may not carry my laptop to the couch when I'm trying to go 'off duty'. Instead, I'll just walk over with my iPad.&lt;/li&gt;
&lt;li&gt;The drawing app I got - trying to replace my paper notebook - would work better with a stylus. Swiping your finger around the screen tends to have a lot of 'drag', and it doesn't feel right, and it feels like it obscures too much of the display.&lt;/li&gt;
&lt;li&gt;I can't speak to the 3G part because I haven't activated it yet. We'll see. It kept pestering me every half hour or so to activate my 3G until I found out the control to turn it off.&lt;/li&gt;
&lt;/ul&gt;&lt;img src="http://feeds.feedburner.com/~r/brady/~4/HMRw1xs6h5Y" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/991999351889889559/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/05/ipad.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/991999351889889559?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/991999351889889559?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/HMRw1xs6h5Y/ipad.html" title="iPad" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/05/ipad.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEIMRng9fCp7ImA9WxBVEU4.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-6810581393826426700</id><published>2010-01-30T17:50:00.007-05:00</published><updated>2010-02-14T02:29:47.664-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-14T02:29:47.664-05:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="braydix" /><category scheme="http://www.blogger.com/atom/ns#" term="LightDesktop" /><title>LightDesktop Valentine's Day Release - now Self-Hosting (ish)!</title><content type="html">&lt;p&gt;So - biggest thing is that I've replaced the horribly-performing WebDAV with a CREST-fs derived writable filesystem. It's nice, writing both the server and client sides of a remote filesystem setup. I'm enjoying it, when I am not feeling like tearing my hair out. Because I am a fearful little wretch of a man, I did not write the 'DELETE' method yet. I'll get there, just have to build up the courage. I think I wrote the client side, I just want to do something super wussy on the server end where I don't delete it 'just in case'...The new filesystem should have several attributes the old one did not have - it should work disconnectedly, it should be cache-aggressive, it should use the cache when disconnected, it should perform well, and it should have some support for symlinks.&lt;/p&gt;

&lt;p&gt;I also modified the 'root window manager' thing - it has a sorta taskbar style doodad, with a wireless strength meter and a battery power meter, and some little quicklaunchey button things. Not configurable yet, but that's probably one of the things that's next.&lt;/p&gt;

&lt;p&gt;I started by making it so that I'm able to compile a relatively simple project, with the storage all living in the Cloud. That compile was actually the root window manager/launcher thing for LightDesktop. Then I moved my LightDesktop dev directory over to a separate filesystem. And then booted up into LightDesktop, with that filesystem available as a secondary FS. Took me a while, but I got to where I can do a full compile, rsync, upload - everything - all from LD itself. I'm a little too afraid to put the entire compile for LD into the cloud itself - lots of stat() calls on lots of files causes lots of traffic, and the performance hit is a bit rough right now. But I'm inching my way there!&lt;/p&gt;

&lt;p&gt;So, performance still is a little rocky - there are optimizations to be made on my end in plenty of places, I'm sure. I every now and then run into a weird problem where the system hangs on boot at some point after mounting CREST-fs. And lots of networking changes will occasionally confuse the filesystem to the point where it doesn't work. I really want it to fail over to the cache when it can't read something, but the allegedly time-out'ed recv/send calls seem to sometimes not work that way. Or maybe it's my DNS stuff. If you've ever done any Unix network programming, I can assure you it is unnecessarily unpleasant, almost all the time. Just going from name to IP is like a page of code, it's horrible. I see why every reasonably-sized app builds its own DNS cache every time, you can get stuck in DNS lookup hell real quick.&lt;/p&gt;

&lt;p&gt;So at this point you could theoretically grab a copy of this thing, boot from it, and develop up a storm on it, building apps for it. I guess I'm kinda doing that now - though my source code is not on the Cloudy CREST-fs filesystem due to my fear of somehow blowing up all of my data (not completely unfounded of course...). But at least from here on out when I'm developing LightDesktop, I'll at least be running it. That's a start. I'm not at the point where I can 'develop from anywhere' until I can get the source into the cloud too - but that's not far off. That will be pretty cool - I'll sit on a VM on my Mac, or on Craptop, or maybe some new Desktop machine I get...or booted off a thumbdrive somewhere. And coding. How cool would that be?&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/brady/~4/xASg_jkxUiA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/6810581393826426700/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2010/01/lightdesktop-valentines-day-release-now.html#comment-form" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6810581393826426700?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/6810581393826426700?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/xASg_jkxUiA/lightdesktop-valentines-day-release-now.html" title="LightDesktop Valentine's Day Release - now Self-Hosting (ish)!" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total><feedburner:origLink>http://www.uberbrady.com/2010/01/lightdesktop-valentines-day-release-now.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEEMRHg-cCp7ImA9WxBTF00.&quot;"><id>tag:blogger.com,1999:blog-14933935.post-1712682955537210373</id><published>2009-12-13T05:26:00.002-05:00</published><updated>2009-12-13T06:11:25.658-05:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-13T06:11:25.658-05:00</app:edited><title>Lightdesktop tweaks</title><content type="html">&lt;p&gt;The console font wasn't fixed-width so using the console was driving me crazy. Fixed. I changed the filesystem to point to the new domain (big pain in the ass). Tweaked the installer and filesystem so the /boot directory is fully under the control of crestfs. New parallel version of crestfs. Fewer pauses, much good. Added make and gcc and lots of stuff so you can now compile things (still not self-hosting though). Put in an ACPI daemon so you can close your laptop lid and the system &lt;i&gt;might&lt;/i&gt; go to sleep (doesn't work perfectly yet). /etc/ is the next directory to get taken over by crestfs, but will be a bit of a challenge because some things like to write in there, and there are a couple of very odd symlinks that point to /proc or /tmp, and crestfs won't let you make symlinks like that.&lt;/p&gt;
&lt;p&gt;Ran into some huge disappointments with davfs2 though - write performance isn't very good, It won't let you connect if you don't have an internet connection, and you apparently can't make symlinks, and all of that really really sucks. I'm going to replace it with something that I figure I will eventually merge back into crestfs. I figured I was going to have to do this eventually, but it came sooner than I had hoped. I already have code for doing HTTP GET requests, and directory listings and so on - basically the 'read' side of the equation - so I don't think it will be too horrible to get the write side going with PUT and POST (what I'll be using for symlinks) and DELETE...&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/brady/~4/01RbPmPHf-g" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.uberbrady.com/feeds/1712682955537210373/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.uberbrady.com/2009/12/lightdesktop-tweaks.html#comment-form" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1712682955537210373?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/14933935/posts/default/1712682955537210373?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/brady/~3/01RbPmPHf-g/lightdesktop-tweaks.html" title="Lightdesktop tweaks" /><author><name>Brady</name><uri>http://www.blogger.com/profile/14736772852272606779</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total><feedburner:origLink>http://www.uberbrady.com/2009/12/lightdesktop-tweaks.html</feedburner:origLink></entry></feed>
