Tag Archives: rant

capistrano considered annoying

So, for the last 6+ months, I’ve had one major elephant on my plate. The eating has been slow, and honestly not very delicious. But something happened yesterday. I realized I had finished.

The proverbial lights came on and I understood Capistrano. I didn’t really like it. But it finally and suddenly made sense after having been a constant irritation for so long.

Capistrano is a deployment system for rails applications. On the tin, it says it can “easily be used to deploy any language” but they’re just kidding themselves. It’s a tool written in ruby meant to deal with the hassles of ruby website deployment. To a non-ruby developer (or more accurately, a non-rails developer), it is so much incomprehensible smoke and mirrors.

I’ve been a programmer for 25 years. I’ve been using Linux for about 20 years, professionally for about 15. I’ve been tinkering with ruby off and on for 5. I’ve recently started teaching my daughter ruby as her first programming language. I should really have been able to figure out this stupid tool much more quickly than this.

I think the bulk of my mental block stems from the way in which I was introduced to Capistrano. Last year, I started at a new job where the head of IT had been using cap to deploy all of our rails apps in ways I did not agree with 100%. There wasn’t anything wrong with what he was doing and it makes plenty of sense. It’s just not the way I’d ever done it myself.

He told me about how cap worked, and explained that we were transitioning between cap 2 and cap 3 – which in the grand tradition of all things ruby is not a backwards compatible change. But before he left the company a few months later, he never explained how to actually bootstrap capistrano on a new system.

One of my first assignments was to make a production environment for an application that one of our rails devs was writing. Staging already worked fine, so I just had to reproduce things with more resources, etc… or so I thought.

There was too much noise.

If I had been a rails developer for a living, I would have been better prepared to sort through the noise. But alas, I was not. I’ve used plenty of ruby over the years for small projects here and there – and for one very large project quite a while ago. But never had a need to use rails itself for anything.

The problem with any web framework is that it is, by necessity, a whole bunch of code sitting in your project written by people who aren’t on your current team. It’s like inheriting a hopefully well documented legacy project along with some outdated contact information from one of the original authors.

Over the years, I have deployed a lot of PHP and Java web pages/applications. I’ve done it by hand and with the assistance of deployment tools. It all makes sense to me.

With PHP, you deploy the source code and assets to a directory accessible by your php interpreter and tell the web server how to reach it. PHP and the web server have config files of their own. The site typically also has its own config files which tend to be clearly labeled as such.

With Java, you deploy a single file that contains all of your compressed assets where your servlet engine of choice (let’s say Tomcat) can see it. The application’s configuration is usually baked into the bundle that you deploy. Tomcat has its own config files separate from the application’s source tree. You run Tomcat, and it serves the website. You then put a real web server in front, similar to how you would with a PHP site.

Ruby… kind of straddles the line between these two, and it hands an additional wrench to the monkey. Rails applications are deployed as source code like PHP. They run a dedicated application server like Java. However, unlike with Java, that application server IS the rails app. You invoke it directly, and it runs itself. This means that app server and application configuration files are kind of mixed together – and it’s hard to tell where one aspect of things ends and another begins.

Ruby also typically makes the general assumption that the application itself will install its own dependencies. Whereas with PHP and Java, you must often install various libraries separately to support their execution – ruby apps ship with dependency lists that you can easily invoke to install everything automatically. So there’s that extra deployment information bundled in with everything else.

So, to recap. To deploy a rails app, you install ruby on a box. You then install one extra utility for ruby that doesn’t ship with it. Then you upload your source code to the server and run that tool. This will go out to the internet and fetch and install all of your dependencies (ala pecl or cpan). Then you can launch the application itself. Then you tell the web server where to find the ruby app just like with anything else.

This is all sane enough, it’s just a different ordering from the other languages. Capistrano gives our monkey a third wrench to hold (in its tail, I guess?). Instead of deploying the application to a self-contained directory, cap starts making symlinks around. It versions subsequent deploys of your app (ostensibly to make rollbacks easier).

There are a lot of symptoms of version paranoia here (yay for abandoning backwards compatibility). When cap runs its bundler install, those libraries aren’t installed system wide, they go into an unprivileged application specific location. This would allow you to run different versions of the same library across multiple applications but makes for a major headache trying to find things if you don’t launch the app just so.

Hang on, one of my programmers is having issues with a Capistrano deploy not making one of the symlinks it was supposed to…

30 minutes later…

ARGH. So.

The problem was because I originally set things up while referencing information from conflicting versions of various tools. Two config file entries later, he’s back and working and I have more grey hairs because of Capistrano.

Seriously. That just happened while I was trying to rant about versioning and documentation. Things like this would not fly anywhere else.

The only real problem with Capistrano is that it is a Rails tool written by Rails developers for Rails developers. They make a lot of cultural assumptions and subsequent shortcuts. It is not very accessible to those of different cultural backgrounds.

Because cap v2 and v3 are different and the internet is forever and because people are lazy, it’s easy to read incorrect documentation that doesn’t remember to identify which versions of tools it applies to.

Because ruby applications ship with so many different moving pieces all jumbled together in one big fat directory, it is impossible for the uninitiated to identify where config files for one of the myriad components end and where the configs for another begin.

Because I inherited an existing project, the SNR was practically zero.

And don’t even get me started on how Capistrano demands passwordless sudo…

I’m sick and fed up with it all, and it’s one of the best tools that I’ve ever had the misfortune of using.

Now I get to go back and add God to the mix before collecting my thoughts and attempting to write a useful tutorial for general Linux admins to get up and running with Capistrano.

mmo-a-week: week 2.5: alganon post-mortem

Well, there’s not much I really want to say here outside of a bit of an observation.

Since I stopped playing Alganon two weeks ago, they have sent me two emails.

  • The first was to advertise that they were giving away free mounts to all beta testers who wanted one. I did not log in to claim mine 😛
  • The second arrived last night and advertised that they really are completely intent on launching in ONE week.

They released a state-of-the-game article monday night to address a lot of their problems. To summarize it all as succinctly (and as snarkily) as possible:

Yeah, there are bugs, lots of bugs, but we’re actually actively patching things that should have been resolved before we declared open beta. We like crunch mode. Sleep is for mortals who plan ahead. We plan on “hitting” a magical launchable degree of quality before December, somehow.

We’ve finally fixed our billing system, so we can charge forners. Downloading the client works again.

We’re still in denial about our rip of WoW being a bad thing. We’re gamers writing a game for gamers, so clearly since we enjoy a bad copy of a polished product, all other “gamers” should too. We’re trying to copy as many features as humanly possible, regardless of the quality or ethics involved. People don’t complain about bugs, they complain about the “similarities” to “other games” they play. We’re not trying to reinvent the wheel or even compete with anything vaguely shaped like a wheel.

Our players who use the forums have drunk the kool-aid. We believe that they will brainwash others, but we don’t want to “steal” players from other games, honest. We’re not in it for the money. We’re all about the ART, man. Clearly we’re not rushing to market to start recouping some of our development costs.

We are totally the first “real” fantasy MMO to launch in two years. Warhammer and Conan don’t count. Runes of Magic and Aion don’t count either. Neither does anything else imported from Asia…

We love you, please don’t hate us for being derivative.

I wish Alganon well, the crazy fools. Really, I do. I just don’t envy the worker drones who’re tasked with making this pig up at the last minute. Surely the insanity isn’t rampant throughout the entire company… just the public facing elements, right? Right? Oh well.

p.s. This week’s report on Ether Saga Online is 2/3 finished. I’ll try to publish it before end of day.

wow torture quest

So… wow. Bartle‘s been getting a lot of press and/or flak for his stance against a quest in WoW that the creators coyly titled “The Art of Persuasion”. Basically, the quest NPC is too impatient to interrogate a prisoner but doesn’t want to dirty his hands with torture – it is against his organization’s rules of operation – so he gives you a cattle prod to fry him with a few times while he looks the other way (all of 3 feet away).

The fact that the quest exists isn’t wrong. The fact that you don’t really have much of a choice in the matter is. You can’t tell the quest-giver “no”. You either have to torture the prisoner or you have to bypass the remainder of the quest chain (which is fairly important if you want anything to do with the Kirin Tor mages).

I did the quest once – on my warlock, the character whose job it is to be a little dynamo of concentrated evil – and I remember standing there for 5 minutes debating before I finally decided to actually zap the guy. I’m not planning on doing the quest chain again on any other characters. Normally, my criteria for adding a quest to my blacklist is that it is boring or a terrible waste of time vs the reward. This is the first quest I’ve ever had to swear off on moral grounds.

So why has this particular quest been singled out? Why wait until now? By every definition in the book, we (players of WoW and numerous other MMORPG’s) have clearly been engaged in innumerable unsavory activities – including torture – for years now.

This is hardly the first time a quest in WoW expects you to use violence to extract information. There are quite a few quests that expect you to beat on people until they talk. There are several quests that ask you to kill couriers for information they are carrying. There are quests where you poison people and quests where you perform horrible experiments on people and quests where you don’t actually have to beat on the source of the information, you just have to prove that you’re willing to do so. It is, after all, a game whose fundamental action is killing.

We play a game where we are asked to role-play as soulless mercenaries who’ll kill anyone/anything for a few bucks – or more likely a shirt that we’re just going to turn around and pawn because it breaks our set bonus. We’ll dig through pig droppings and harvest organs and collect on debts owed to thieves and steal apples if we accept every job offer that comes our way.

The circumstances behind this particular quest, however, are much more obvious. This particular quest NPC says:

You see, the Kirin Tor code of conduct frowns upon our taking certain ‘extreme’ measures – even in desperate times such as these.

You, however, as an outsider, are not bound by such restrictions and could take any steps necessary in the retrieval of information.

He then hands you a “Neural Needler”, which “Inflicts incredible pain to target, but does no permanent damage.” You then have to walk 3 feet to a man chained into a chair and use the needler on him five times. The ‘conversation’ goes something like this:

  1. Pathetic fool! A servant of Malygos would sooner die than aid an emeny…
  2. Aargh! Do your worst, {class}! I’ll tell you NOTHING!
  3. Aahhhh! Release me! I am of no use to you. I swear it!
  4. Stop! I beg you, pleae stop. Please….
  5. Alright! I am beaten. {information you wanted goes here} Your mission is folly!

But you can keep zapping him a few times before turning in the quest…

  1. I’ve given you the information, {race}! You’re wasting your time….
  2. Noooo! This tortue is inhumane! You have what you want… why don’t you just kill me?

Even “better”… you can apparently get a fresh needler (I have not confirmed this) and continue frying the guy, just for fun…

  1. What more can you possibly want, {race}?
  2. Stop! Please…
  3. How can you possibly bring me lower?
  4. What more can you take away from me?
  5. You aren’t even asking me questions…
  6. Are you trying to meet the real me?
  7. You’ve got a darkness in you, {race}.

So, whether this is some kind of weird statement on current events or not, several people at Blizzard apparently think that torture can be useful and want to spread that opinion to their audience of millions. I mean, c’mon, it’s not like children play this game, right? …

Regardless of why the quest was written, why it was included in the game, and why it’s standing out above all of the other heinous things players have been asked to do in the game… it was a mistake and needs to be revised to avoid railroading players into a choice between being evil sadists and quitting the game. Everyone involved should be ashamed of themselves.

seriously, burn the stables already

Back in the lead-up to Wrath, I’d suggested that one of the Hunter class’s biggest problems was the stable system. In my experiences over the last few days with Al, I hold this opinion more firmly than ever.

Every class has the option of carrying a second set of equipment around for different circumstances in instances. A cat druid might carry healing eq for certain boss fights where the extra hot is needed, any warrior worth two beans is going to have a shield somewhere on his person, etc…

Hunters and warlocks are both already heavily penalized in the inventory department, though to be fair they really don’t have much need to switch gear between fights. Hunters permanently sacrifice a bag slot to ammunition, and warlocks need to carry lots of shards – for which they can optionally choose to employ custom bags.

After spending only 17 points in demonology, a warlock can cycle through 3 different pets in ~6 seconds. They can adapt for different fights as necessary. To them, changing pets is roughly as difficult as changing weapons. A warlock’s pet (or often their lack thereof) is simply a buff like that granted by another class’s stances and auras.

If a hunter wants to switch pets, they have to run to the nearest town. No switching gear or rebuffing between fights for them.

Aspects aren’t big enough to warrant this discrepancy. They are essentially:

  1. I am shooting things
  2. I am out of mana because I was shooting things
  3. I am corpse running after my group just wiped
  4. I am fighting a boss that does nature damage
  5. I am not running out of melee range for some bizarre reason

So in normal practice, a hunter has two states – killing and in-combat downtime. Aspect of the viper is a complete joke since 3.0. Requiring players to alternate between the two is a big design flaw, IMO.

So if aspects aren’t a hunter’s “stances”, pets are the big candidate for the role.

Just like a paladin can strap on his shield to tank or put on a dress to heal, a hunter can use a gorilla to tank or a chimera to crowd control or a dinosaur to eat things… as long as he returns to town first.

Please, Blizzard. Just put hunter pets in the spellbook already.

Of course, my nefarious reasoning behind ALL of this is just so I can carry a set of 5 pets into a boss fight and resummon a new one when the old ones melt under his AoE aura – allowing me to actually have a pet out for the entire fight and waiting until after the fight to rez them 😉

php autoload

As of version 5.0, PHP has had the ability to dynamically include required classes as needed – without requiring the developer to manually include all possible dependencies beforehand. This means that in cases where your code execution never touches 39 of the 40 classes in the project, it loads, parses, and runs that much faster.

There is a performance hit for actually having to call the __autoload() method, but if you’re in a situation where the hit for executing a few extra comparison calls is unacceptable… you probably aren’t developing in PHP in the first place 😉

Almost all of the php I’ve written in the last 2-3 years uses autoloading, and it has probably saved me hundreds of hours of aggravation.

In most of my projects, the first line of any script or class usually looks something like this:

Then lib.php usually reads something like this:

And that is all that is strictly required to make the magic happen. It is fast, it is easy to understand, it is easy to use. You can use require_once() or include_once() and there is very little meaningful difference.

I’ve looked around the net and found several other attempts at improving on this simple mechanism. But they invariably overcomplicate things. They attempt to recurse source directories, cache filename->class differences to the filesystem, and otherwise turn what should be a simple filesystem operation that the php environment supports natively into a mess of exception handling and wheel reinvention.

There are obviously theoretical instances where you might want to have more than the one require_once/include_once line… but I’ve honestly never encountered one myself.

I mean, you could try to throw an exception if the file didn’t exist or otherwise failed to load… but nothing will happen. Failure to instantiate a nonexistant class is a fatal error in PHP, and will be handled as such with or without you – preempting any attempt at throwing an exception.

The only thing you can add is a bit of extra diagnostics or maybe logging to a separate location.

Assume that we have a file ‘test.php’:

If autoload.php contains a simple simple autoload function that uses require_once(), and Frog.php doesn’t exist anywhere in your include path, the results will look something like this:
[code]
ammon@kif:~$ php test.php

Warning: require_once(Frog.php): failed to open stream: No such file or directory in /home/ammon/autoload.php on line 3

Fatal error: require_once(): Failed opening required ‘Frog.php’ (include_path=’.:/usr/share/php:/usr/share/pear’) in /home/ammon/autoload.php on line 3
[/code]
If we had used an include_once() call, the output is similar, but slightly more informative:
[code]
ammon@kif:~$ php test.php

Warning: include_once(Frog.php): failed to open stream: No such file or directory in /home/ammon/autoload.php on line 3

Warning: include_once(): Failed opening ‘Frog.php’ for inclusion (include_path=’.:/usr/share/php:/usr/share/pear’) in /home/ammon/autoload.php on line 3

Fatal error: Class ‘Frog’ not found in /home/ammon/test.php on line 4
[/code]
So that’s probably a bit more useful in tracking down the error. Require calls don’t return anything – they throw a fatal error on failure. Include calls, however, return FALSE on failure and TRUE if the file is (or, in the case of include_once, has already been) successfully included. So you can include_once() and write to a separate logfile (or to the output stream…) if you need more information than the fatal error already provides you.

<rant>

To those who insist on giving your classes and their containing files different names… umm. Wow.

If I have a class called DatabaseConnection, I’m going to put it in a file called DatabaseConnection.php. If I’m working with strange people who somehow don’t think that is explicit enough, I might call it DatabaseConnection.class.php and tweak the autoload method ever so slightly to compensate. There’s no good reason to put it in a file called projx-database_connection.incl or something. No. There isn’t.

If you want to organize your classes into a meaningful directory structure… good for you. Use PHP’s built-in include_path ini option. Don’t waste time trying to cascade down a directory structure searching for the classes – just make sure your includes are all in a set of reliable locations. You don’t actually have to edit the php.ini file and bounce Apache or your php-cgi processes, just define the additional include paths in the same file where you define your autoloader:

Naturally, you could turn that into some function calls to dynamically register and unregister directories, etc… but at that point, you’re probably hurting yourself again. If your codebase is being reorganized enough to make maintenance of the list of include dirs onerous without full time intervention, something else has probably already gone very wrong. At best, the code probably doesn’t work anyway, so any brief delay in updating the list can’t hurt any more than whatever else is happening.

</rant>

But seriously. __autoload() is your friend. It will help clean up your code if you let it. It can help enforce naming conventions. It can even improve performance… so long as you refrain from using it to shoot yourself in the foot. 😉