Any Way You Slice It

It’s been over a month since I’ve been with Slicehost so I figure it’s enough time to make an assessment. Especially now that the MacUpdate promo is over, I actually have a sense of how well things hold up under load.

For those who don’t know, Slicehost is a hosting provider. What sets them apart from shared hosting providers is that they provide you with what they call a “slice” (other similar providers may call it a virtual private server or VPS). What this is is a virtualized server of your own. From your perspective, it’s like getting a dedicated server. You choose what OS you want (which right now consists of different Linux distributions) and you get root access so you can do whatever you want.

It differs from shared hosting in that your slice is like it’s own machine. It gets a guaranteed amount of memory and CPU so even if your neighbor is a hog, it won’t affect your slice. Because of the way that the Xen virtualization works, it is impossible to oversell on capacity.

Compared to getting a dedicated machine, it’s much cheaper and you aren’t tied to specific hardware. Blown power supply? Not your problem. I don’t know exactly what they do in this case, but I imagine they can move your slice to different hardware as needed.

Set up

You can read my original report on getting set up. You are expected to set up and administer the slice yourself. If you have the inclination and need a high level of control, then this is probably for you.

It only took me a weekend from getting my slice to having everything migrated over. Of course, being the tweaky type that I am, I spent some days playing with it and optimizing it. One of the benefits and dangers of having full control.

Upgrading

When I launched the new store, there was a problem. Ruby on Rails is a memory hog and as a result, I needed to upgrade to a bigger slice. Fortunately, Slicehost automates all that. Just log into the management console and request the larger slice. It takes a little while for the slice to get prepped but during that time your slice is still up. The downtime for the reboot was short (less than a minute) and that was it. The fact that it’s automated is a big deal to me as it means I can do it on the fly without doing a drawn out back and forth with a support person.

Traffic

As you may or may not know, Hazel was included in the recent MacUpdate bundle. Before the launch, I upgraded my slice again to 1024M in anticipation of the load. Turns out, this was unnecessary. The 1024 slice never broke a sweat. The load went up briefly to 0.4 once. Apache connections stayed below the upper limits of what a smaller slice would have been able to handle. Traffic was about 150K requests a day at its peak. I don’t really have a frame of reference for that except that it’s a good bit more than I usually get. In short, the 512 slice would have been able to handle it fine. The slice has performed better than with my previous providers and I haven’t noticed any slowdowns or downtime (except for when I restart things for maintenance). With the promotion over, I’ve downgraded my slice and things are still running smoothly.

* * *

After all this, I’ve only contacted support twice. Once in the beginning just to say hi and once today for an issue that ended up being an Ubuntu thing. In both cases, I received responses within the hour. Granted, I’m doing a lot of the things that support at other hosting services would do for you. It’s a trade-off between effort and control and I’m at that point where I need more of the latter. For the things I really care about, keeping the machine and network reliable, there has been nothing to report, and that is how it should be.

It’s too bad most providers price on bandwidth and storage space. I would have happily paid more per month if I could get higher availability and reliability (with the ability to run RoR - sorry Pair). Of course, with everyone claiming 99.999999% availability, it’s hard to differentiate oneself on this front so providers seem to just pile on the bandwidth/space like extra gravy hiding the bad meat.

I feel like VPSes are the future of hosting. The amount of computing power that you can cram into a 1U rack space is far more than most of us need or want to pay for. But virtualize it and divvy it up and you have a great scalable model for doing dedicated hosting. It’s probably greener too but I’ll let the hippies make a determination on that.

Comments (2)

Adventures in Debugging: Pref Pane Poppin’ Aplenty

As you may or may not know, Hazel is packaged as a preference pane. While you do all the configuration via the preference pane interface, the actual work of running your rules is done by background processes. The commandline tool that actually runs the rules is stored inside the pref pane bundle. I’ve kept it in the Resources part of the bundle for no good reason except that’s the catch all for all your bundle stuff. But then I thought, “why not stick it in the MacOS dir. That’s where executables are supposed to go, right?”

So, I went into XCode and created a new “Copy Files” phase to copy the built executables into the “executables” dir (which ends up being the MacOS dir in your bundle). I modified the code that launches the program to look in the right place (NSBundle’s -pathForAuxiliaryExecutable: for those of you keeping score at home). It seemed to work. My bundle was now a tad tidier with things in their proper place.

Later on, I was testing something else and noticed that when Hazel was running certain rules, the pref pane icon would show up in the dock and then disappear when the background program was done. Strange enough that a pref pane icon would appear in the dock; stranger that it was being triggered by a non-GUI program. More testing revealed that it happened when Hazel was executing AppleScripts. I tried isolating the AppleScript parts. I checked all sorts of paths. I couldn’t figure out what was causing it. The Pope was in town so maybe he was messing things up somehow.

I checked previous versions to isolate when the bug was introduced and discovered it was only in the last set of changes. Moving the executables back to Resources fixed it.

Problem solved but I had no idea why. After muttering about it in IRC, Mike Ash casually throws out the explanation: “the binary is hitting the window server, the window server notices that it’s in an executable directory of a bundle, sticks it in the Dock.”

Of course, it all sounds so simple when you hear the answer. Calling the AppleScript created the window server connection which then prompted it to throw the icon in the dock as if it were a regular app. Not sure how long it would have taken me to figure that out on my own.

The lesson here is that when faced with a crazy bug, ask Mike Ash. Really, though, don’t do that. He’ll crash his glider into me next chance he gets. The real lesson is that you should be careful about putting executables for background programs in the MacOS directory of your bundle.

Ok, so I can’t pin this one on the Pope. All I know is that I don’t get these types of problems when the Dalai Lama is in town.

Comments (2)

MacUpdate Bundle

If you haven’t seen the ads or announcements yet, Hazel is in the MacUpdate bundle that starts today. 10 great apps for $65.

Bundle mates include:

Parallels Desktop

Banner Zest

Sound Studio

DVD Remaster

Typinator

StoryMill

Leap

MenuCalendarClock

Art Text

This is the first bundle I’ve been a part of so I’m not sure what to expect. I’ve beefed up the server so hopefully the site will stay responsive throughout the promotion. When it’s all said and done, I’ll post my thoughts on participating. In the meantime, grab it while it’s hot.

Comments (1)

Ruby on Rails: First Impressions

In getting Potion Store integrated with my site, I had to learn Ruby on Rails. RoR has always been one of those things I’ve been curious about so I saw it as an opportunity to dive in. I present here a first impression. Note that these are impressions. They represent how I perceived things coming to it for the first time. While chances are that these perceptions are inaccurate, there’s something to be said for seeing how things appear to fresh eyes.

Ruby is an interesting language. It appears to be very flexible and dynamic, allowing you to do a bunch of really neat things that you can’t in most other languages. Note that these features aren’t really unique to Ruby. My sense is that Ruby is not a distinctive language in itself so much as a mostly good mix of other languages. I say “mostly” because I’m not sold on the syntax. It reminds me too much of Perl. It’s like they created a great new flavor of ice cream and then mixed in glass and razor blades.

My advice to those picking up Rails for the first time, get the Rails book and read the first few chapters before diving in. I found the online tutorials kinda annoying and not as good at explaining the structure and conventions that Rails relies on. Rails’ strongpoint is streamlining common tasks and functionality but to do so, it expects things to be laid out in a certain way. The other thing that takes time to figure out is the “magic” that Rails performs at certain points. One of the great things about Rails is how certain things are automatic. Very little glue needs to be coded and I feel that’s a wonderful thing. On the downside, sometimes this magic makes it hard to figure out what’s going on. For instance, some classes had naming patterns for their methods that you had to find out about in the documentation. I found the quality of the documentation to be a bit uneven which didn’t help in some cases.

I feel most of the problems with Rails are less about the design and more about the implementation. For instance, Rails is a memory hog. And because Rails is single-threaded, you need to have at least two of these things sitting there to get any sort of concurrency. When I deployed my store, I had to upgrade my SliceHost slice as the 256M slice wasn’t cutting it (remember I’m also running mysql and PHP stuff). Also, I felt deployment was a bit clumsy, as I had to set up a cluster of mongrel instances to run my app with apache acting as a proxy. While I see that there is a mod_ruby for apache out there, no one I know recommended it. Nonetheless, I felt like I had to deal with more moving parts than was necessary.

In a nutshell, Rails: great, Ruby: enh. If you are going to buy a book on it, get the Rails book first. It has an appendix on Ruby that should be sufficient for most things. If you want to go deeper with the Ruby side of things, you can get the Ruby book as well but personally, I could have done without it.

Overall, I like the platform but at the same time, I can see that it’s relatively immature and has some ways to go. I’m pretty much tied to RoR for now since it’s what the store is written in but that’s not a bad thing. That said, I also am not so amazed that I am going to join the Ruby cult.

Nonetheless, RoR feels like how a web framework should and less like a bloated platform where you end up installing a hundred frameworks requiring just as many config files to be edited to solve non-existent problems that are justified because someone gave it a fancy technical name along with a contrived design pattern to fix it (if you need a hint as to what I’m referring to: “starts with a J”). RoR seems to be able to identify and address the actual problems people run into when creating web applications, all the while keeping it relatively simple, and that is refreshing to see.

Comments (6)

New Store

In my recent quest to deal with some long needed “home improvement,” I’ve just rolled out my own store based on PotionStore. For those that don’t know, PotionStore is an open-source store implementation done by Andy Kim. It’s used by PotionFactory, of course, as well as a few other shops.

Until now, I’ve been using Kagi for all my payment processing. Kagi is great for someone starting out as they provide the store, deal with taxes and can even provide a license number generator. I think when you are doing your first release, outsourcing the commerce side to someone else can save a good deal of time.

So why am I switching off Kagi? Mainly much lower commissions on each transaction and more control over the store itself. I was finding that the commissions were adding up to significant money as my volume rose and there were certain features I wanted to add that I couldn’t. On top of that, there was a bit of confusion regarding having customers dealing with a 3rd party.

Unfortunately, now with my own store, I am going to have to charge sales tax to New York residents. One of the downsides to living in the same state as me. Trust me, I’m not looking forward to doing the tedious sales tax filings.

Using PotionStore has been great. The integration took a bit longer as I had to learn Ruby on Rails at the same time (more on this possibly in a future post). I also had to change the code a bit for certain requirements I had (sales tax, license files, family packs, etc.). My thanks to Andy for sharing his code. I hope to see other devs pick it up and maybe even contribute to it. Oh, and a thanks to Gus Mueller for letting me crib some Javascript from his store.

The result of all this is a store which I hope looks nicer and has a more streamlined flow. I’ve added the ability to download your licenses immediately as well. You’ll still get them emailed to you but this way, you’ll get instant satisfaction coupled with some level of redundancy.

So, give it a spin. Maybe even buy something :). If anything goes wrong, or even if everything goes right, I’d love to hear about it.

Comments (2)

Modal Glue

Recently, Quentin Carnicelli of Rogue Amoeba asked if there were NSResponder methods that you could hook your “OK” and “Cancel” buttons to to dismiss a modal panel (or sheet). As far as I knew there wasn’t but, gosh darnit, that would be a useful thing to have.

To clarify what I’m talking about here, when you run your own modal window or sheet with “OK” and “Cancel” buttons (or some equivalents), you end up hooking those up to methods that dismiss the window/sheet, stop the modal session and return some code (either one for confirmation or cancellation). Most of the time, you end up writing the exact same code. It’s glue code that shouldn’t have to be written.

Now, if you look at NSResponder, you’ll see all sorts of action methods in place. Sticking these glue methods into NSResponder will allow you to hook up your “OK” and “Cancel” buttons to the “First Responder” in IB. The idea here is that there is a default implementation that will close the current modal window or sheet and set the return code to either NSOKButton or NSCancelButton. With this, your code can act more like it’s using NSRunAlertPanel() or NSBeginAlertSheet() by just interpreting the return code.

I’ve created an NSResponder category with the methods -confirmModal: and -cancelModal: to which you can hook up your “OK” and “Cancel” buttons in IB. Note that you may have to manually add the methods to NSResponder in IB as it doesn’t know about them.

Now NSResponder’s versions of these methods don’t actually do anything besides pass it on to the next responder. The main part is in NSWindow, which overrides it. It will check to see if it’s the current modal window or sheet, order itself out, stop the modal session and send back the appropriate code. By using the responder chain, this mechanism will find the “nearest” modal window. Note that it is assumed here that the buttons to dismiss a modal window are in the same window. If you want to dismiss it from a different window, it may or may not work (depending on the responder chain and other subtleties such as the odd specification of NSWindow’s -isSheet method). I can’t think of a non-contrived case where you’d want this or care but if one comes up, let me know.

So here’s the download. Suggestions, questions, bug reports appreciated.

modalresponder.zip

Comments (2)

New new home

If you are reading this right now, then that should mean that the host migration was successful. No, I didn’t accidentally re-post my last article. I’ve moved Noodlesoft to yet another hosting provider. Noodlesoft is now on SliceHost.

Unfortunately, things didn’t work out with WebFaction so I decided to go shopping again.

While many people were recommending SliceHost, I resisted as I wasn’t relishing the idea of doing sysadmin work. I’ve done my fair share in my lifetime, including compiling kernels, setting up firewall rules and mucking with sendmail.cf files. The whole purpose of using shared hosting was that I could pay someone else to do it. Nonetheless, I found myself in need of a higher level of reliability and control. I had to bite the bullet.

I signed up and within minutes, was logged in to my slice. And oddly enough, I found myself actually enjoying setting up my server. Sure, it took some time to get everything up and running but not as long as I expected. It’s put together the way I want and if something goes wrong, it’s hard to beat the response time of going in and fixing it myself. It’s not for everybody but if you know what you are doing then I say give it a try. I would recommend paying extra for the backup feature where you can save snapshots (or have snapshots automatically taken daily or weekly). Restoring slices from these snapshots is quite easy in case you mess up or something else goes wrong. They also have articles on how to install most of the software you’ll need to get up and running. My only beef right now is that I’d like more snapshots slots available (you only get 3).

Here is the obligatory/shameless SliceHost referral link in case you are interested in signing up.

Oh, and I am keeping my DreamHost account for things such as hosting my mail. Also, since DH’s plans offer ridiculous bandwidth, it’ll be good to have as a backup when there’s some sort of burst.

And because it’s what I’ve been dealing with for the past couple weeks, you’ll probably see some sysadmin articles from me in the near future. I’ve even added a “System Administration” category. I’ll post a report on SliceHost and my experiences with VPS hosting in a month or two.

Comments (5)

New home

If you are reading this right now, then that should mean that the host migration was successful. You probably didn’t notice anything but Noodlesoft has switched hosting providers. It’s been a long time coming, but I’ve moved the site from Dreamhost to Webfaction (note: this is an affiliate link).

The transition had its share of bumps and glitches as the two providers do things a bit differently. Except for the forums being offline during the migration, hopefully you shouldn’t have noticed a thing. If you do find anything not quite right, please let me know.

It’s too early to tell whether this was a good move but I’ll post a report/comparison after I’ve developed a track record with the new provider. In the meantime, I’m keeping my fingers crossed that nothing blows up.

Comments (5)

My (Real) Desktop

It seems customary for people to post pics of their workspaces and Rands’ recent post has spurred me on to post mine. I’ve been spending this early part of 2008 clearing out my desk area so the timing is a bit serendipitous. I’ve finally packed away my old, dusty PC, which is now in the other room ready to be given to a friend. I’ve also installed a cable management solution which gets most of the cords and cables off the floor and (mostly) out of sight.

So, here it is (pics hosted on Flickr):

NoodleDesk NoodleDesk - Close Up

It is also in Rands “Pixel Rigs” group where you can find other people’s setups.

Some notes:

  • The cheese grater on the left is a PowerMac (2.3GHz DC). It is being retired in favor of the Mac Pro next to it. It was the machine I originally developed Hazel on. Will be looking to sell it so drop me a line if you are interested in it.
  • The monitor on the left was intended as the second display for the main machine but is attached to the old PowerMac for the time being.
  • I like large tabletops, but getting the second monitor cut me off from the left side of the desk. Real desktop space sacrificed for virtual.
  • There is a scanner hidden away behind the left monitor. It’s a very low traffic item so I don’t mind having to get up to get to it.

Additional pop-up notes available on Flickr.

By the way, this is my desk on a good day. Unfortunately, I haven’t ported Hazel to RL (real life) so my desk can accumulate quite a bit of stuff. With great desk space comes great clutter.

Comments (3)

Happy Fun Leopard Bug Time: NSCalendar

Yes, folks, it’s Happy Fun Bug Time where I talk about what has been making me tear my hair out recently. In this installment, we talk about NSCalendar.

NSCalendar has a method called rangeOfUnit:inUnit:forDate:. What this method is supposed to do calculate how many of one time unit are in another. For instance, how many days are in a particular month. Since date calculations can get tricky, with daylight savings, leap years and all, this method is quite handy.

Or, it would be handy if it didn’t suffer from some pretty bad bugs on Leopard. At first, I tried something like the following to calculate the number of days in a given year:

  range = [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit
                                             inUnit:NSYearCalendarUnit
                                            forDate:[NSDate date]];

  NSLog(@"%@", NSStringFromRange(range));

Given that this is a leap year, I’d expect “{1, 366}”. What do I get? “{1, 31}”. I suspect that wires got crossed with the days-in-a-month calculation. Oh, but the fun doesn’t stop there. Try this at home (kids: do not try this at home):

  NSCalendarDate          *date;
  int                     i;

  date = [NSCalendarDate dateWithYear:2007 month:1 day:1 hour:0
                               minute:0 second:0 timeZone:nil];

  for (i = 0; i < 365; i++)
  {
    range = [[NSCalendar currentCalendar] rangeOfUnit:NSDayCalendarUnit
                                               inUnit:NSWeekCalendarUnit
                                              forDate:date];

    if (range.length != 7)
    {
      NSLog(@"Date %@ has week of length %d", date, range.length);
    }
    date = [date dateByAddingYears:0 months:0 days:1 hours:0 minutes:0 seconds:0];
  }

This cycles through each day of last year (2007) and calculates the number of days that week. Now, having just recently lived through that year, I think I can say with some certainty that no week had any more or less than 7 days in it. The above code prints out any oddballs. If you run it yourself, you find that quite a few days are in weeks exceeding 7 days. Upon closer inspection, you find that any day in a week straddling two months reports the number of days in the month, not the week. On weeks fully contained within a month, it reports 7 days. Again we are seeing a tendency towards the days-in-a-month calculation. Someone really likes computing that.

I’ve filed a bug report (rdar://5704940 for you Apple folks). Unless I’m doing something really wrong here or there were some time distortions last year that I was unaware of, you may want to avoid using NSCalendar’s rangeOfUnit:inUnit:forDate: on Leopard for the time being. Thinking about it though, the time distortions would explain a couple weekends…

Update (Feb. 1, 2008):
I strongly recommend reading the comments. Thanks to Chris Suter for explaining what Apple’s logic is in doing it this way. We all thought he was nuts at first but it appears that he was just explaining Apple’s craziness.

In short, things probably are working as designed by Apple. I still think the design is flawed and that it is horrendous API. It seems that, in Apple’s mind, Leopard is correcting a bug in Tiger (in other words, the intuitive and useful behavior in Tiger was a bug).

The original point stands that one needs to take care with -rangeOfUnit:inUnit:forDate:. It seems to be only useful for specific combinations of units and given the change in behavior between Tiger and Leopard, it becomes even more of a headache. If Apple is going to continue with this interpretation, then they should just treat these computations as undefined since the results are misleading.

Comments (17)

« Previous entries