Route definitions matter

Since this past friday, I’ve been dedicating the majority of my time to getting our RSpec tests to pass on our API orders controller. Being that I was tasked with adding some features to this endpoint, I wanted to make sure the existing tests were passing before writing new ones. This would give me a good baseline to begin work and ensure that my code functions as required.

Now, this particular component of our system has gone through a lot of refactoring in the last 6 months and the tests haven’t been kept up, so there were a bunch of failures that were just the result of out of date tests and were very easy to get working again. Then came this doozy.

First some background on the system:

When creating the order in the system, we have 2 endpoints that actually point to the same create action in our orders controller. This is defined in our routes.rb file as follows:

resources :orders, :only => [:index, :show, :create, :update] do
  post :another_action, :on => :collection

  # the problem action is right here:
  post :action_in_question, :on => :collection, :action => :create

  member do
    post :a
    post :b
    post :c
  end
end

With this, one is able to post to /orders or /orders/action_in_question and both will hit our create action, but behave slightly differently.

We do this with code like the following:

if request.path.include?('action_in_question')
  # special treatment
end

The problem arose when we would call post :create, post_params on the orders controller. The URI exposed to the controller always included action_in_question.

When running rake routes I could see that the POST /orders/action_in_question route was always listed before the POST /orders action as well, so I focused my energy on solving this.

The solution was to ensure that this action_in_question action would be lower down in the list so it wouldn’t be automatically generated by RSpect. This was accomplished by changing the above route to look like:

resources :orders, :only => [:index, :show, :create, :update] do
  post :another_action, :on => :collection

  # the problem action is right here:
  post :action_in_question, :on => :collection, :action => :create

  member do
    post :a
    post :b
    post :c
  end
end

# re-open this nested route and declare action_in_question here
resources :orders, :only => [:index, :show, :create, :update] do
  post :action_in_question, :on => :collection, :action => :create
end

That successfully solved our issue and the tests now generate the correct URI.

Capnotify and the future of Capistrano notifications

For the last couple of weeks I’ve been working on a new framework to handle Capistrano notifications. Previously I’d created Capistrano plugins for grove.io and for mailgun and it was a great learning experience.

I started really thinking when we began using HipChat at the office. I discovered that the HipChat gem (here) had Capistrano support, but had a minor bug relating to how we used the branch variable. It turns out that anyone who writes a Capistrano notification gem is going to re-invent the wheel each time. Also, if one sends notifications through several channels, chances are that they want consistent language and behavior for these notifications.

Also, I really like the layout of my capistrano-mailgun gem’s emails and thought it would be great to not have code duplication if I decided to have a similar look and feel for another notification gem.

Enter Capnotify. Capnotify is a Capistrano plugin specifically for providing consistent behaviors and language for your notifications. Ideally, any notification gem would be built on top of Capnotify and anything that speaks Capnotify could modify those behaviors. It also provides a consistent interface for the user of the gems to modify that language across any extensions that they might load.

Capnotify is currently in pre-release on rubygems.org and I have a pre-release of the capistrano-grove gem as well, that’s using Capnotify.

Before I officially release it, I’m hoping to get some feedback to see what works for people and what doesn’t. Are the built-in messages and templates high enough quality? Is it extensible enough?

Capnotify was designed to not only be a platform for other gems to be built, but also function as a stand-alone entry-point into any existing notification system that someone might have. It provides a series of Capistrano triggers and default messages, for example, after a deployment is complete, you could have something like the following:

on(:deploy_complete) do
  MyNotificationGem.send_message( capnotify_deployment_complete_msg )
end

Documentation is about 80% complete for Capnotify and should be 100% complete for Capistrano Grove, so check them out:

See the associated READMEs for installation and usage instructions and feel free to submit issues or email me directly with questions.

Looking for beta testers- Capistrano users

For the last couple months, I’ve been working on a new project. It’s essentially an add-on for Capistrano that allows you to use your Capistrano configuration to run Chef recipes on your servers.

The project is Toque; which is the French word for a chef’s cap (well, technically it’s a toque blanche, but that’s too long of a name). It’s hosted on the github at the following URL:

https://github.com/spikegrobstein/toque

The gist is that you can do cool things like this:

recipe :user
recipe :logrotate, :roles => [ :web, :app ]

set :deployuser, 'myapp'
set :adminuser, 'sysop'

set :deploy_user_shell, 'zsh'

and then execute

cap chef:run_recipes

At this point, the deploy user will be created on all servers and the logrotate recipe (for your rails logs; using your deploy_to/shared_path variables) will be run on your web and appservers.

So, I’m looking for 2-3 people to use this on their apps. I’ve been using this on 3 applications for the last 4 months and it’s been treating me well and I’m ready to get a couple more people on it to vet the usability and weed out some bugs and try to figure out if there are some built-in recipes that I’m missing.

All our apps use the multistage plugin, so I’d like a person who doesn’t use that, if possible.

I will totally hold your hand and get you up and running and support this, so if you’re interested, drop me a line at me@spike.cx or tweet at me @spike666.

Please let people know about this since I’m not sure I know enough people who are deploying with capistrano.

Thanks!

symlink_fast 1.0.0 released (Capistrano plugin)

I just released version 1.0.0 of symlink_fast. This is a plugin for Capistrano which simplifies post-deploy config symlinking by providing an interface for the task and doing it all in a single call to run. On larger application deployments with large numbers of configs that need to be symlinked, the time savings can be significant.

symlink_fast has been released as a gem on Rubygems.org. It can be installed either by typing:

gem install symlink_fast

or by adding the following to your Gemfile:

gem 'symlink_fast'

There is a Github page for the project:

https://github.com/spikegrobstein/symlink_fast

mcwrapper 1.5.0 released

after a much too long hiatus, a new version of mcwrapper has been released. A new branch has been created for it: stable/1.5 as well as a new 1.5.0 tag.

This version of mcwrapper comes with quite a few additions, of which, the most important are the following:

  • a plethora of exit codes for more robust scriptability (see source for complete list)
  • install action for install wizard for minecraft_server.jar which will download and install the latest version
  • upgrade action which gracefully stops the server, upgrades minecraft_server.jar and starts it back up again
  • an about action for getting additional information about the project
  • documentation for backup action
  • restore action for restoring from previous backup
  • prop action dumps entire properties file if no property is specified
  • mcwrapper now monitors the server to ensure that it’s running. If it exits, mcwrapper will also exit (no more zombie mcwrapper processes)
  • various optimizations and code cleanup

There’s just no decent media centre devices

so I’m reading this article:

http://deviceguru.com/google-tv-vs-apple-tv-vs-boxee-vs-roku/

and I’m now 100% convinced that there is no decent media centre device. They’re all too locked down to do anything useful as you’re at the mercy of the manufacturer to resolve bugs and implement new features and support new media sources.

I think the best bet is to purchase/build a real PC and drop media centre software onto it (eg: XBMC, Boxee, Plex, whatever). With that, you can play any format and aren’t limited by features because even at a worst case, you can use VLC or a browser (Chrome, Firefox) to play video from an unsupported file format or site.

It’s just disappointing that computer manufacturers are beginning to drop support for media centre PCs lately. Dell had this awesome $250 machine (I think it was called the Zinio) which they discontinued. It was capable of playing 1080p video including flash video, had HDMI and good sound support (I forget the details of that). There was this other company that was shipping a smaller similarly priced and similarly spec’d machine with an even less expensive bare-bones model, but I can’t seem to find the info for that guy.

It should be possible to deliver a machine that’s powerful enough to do all the video stuff, along with running applications (eg: SickBeard) and web for < $400. The big win would be to have decent resource management so that when it’s playing video, it can guarantee resources to the video so it doesn’t skip while other background processes are running.

I’ve got my MacMini for my media centre and it’s ok, but it’s kinda expensive to use strictly as a HTPC and playback suffers when files are being copied while I’m watching high-bitrate videos.

Too bad no manufacturers are really targeting this market. They’re all concerned about racing to the bottom and delivering customized experiences. They should pick up an open source project and extend it and ship it on their device. There are plenty such projects out there and they’re quite mature.

mcwrapper 1.4.2

Last night I released version 1.4.2 of mcwrapper. This fixes a major bug that cropped up recently involving the mechanism that reads commands from the FIFO. A nice Redditor fixed the bug, refactored my function and sent me a pull request last night and after a little QA, I merged his code and tagged the 1.4.2 release.

When I release 1.5 (towards the end of september), it will have an updater rolled up with it, so updating mcwrapper will be much more painless in the future.

As usual, you can either git pull if you cloned my repo or download the new version and manually update from one of the following locations:

and mcwrapper’s project page is located at:

mcwrapper 1.4 released

I just released version 1.4 of my mcwrapper application. This update improves usability, and adds a couple new features. Overall, it’s a minor release.

Changes include:

  • New log action. Will show server.log output in real-time.
  • Added new BACKUP_ON_EXIT config option. When enabled, this will create a backup whenever you stop the Minecraft server.
  • Added new scripts which can be double-clicked to start/stop the server and create backups. This makes it easier on commandline-impared users.

1.4 also includes an enhancement from 1.3.1 (a silent release) that fixes a bug where mcwrapper will slowly eat all the memory on your system as it reads commands from the FIFO. This was caused by using a recursive function when a simple loop would have been sufficient.

I’m aiming to get 1.5 released by the end of September which should include both launchd and ubuntu init scripts, backup restoration and other enhancements.

mcwrapper’s GitHub project page is located at the following address:

https://github.com/spikegrobstein/mcwrapper

You can download 1.4 using the following links:

mcwrapper v1.1.0 released

I updated mcwrapper to fix some bugs since my last post. mcwrapper now creates the pipe properly and allows for more configuration options.

I also added a new script called mcbackup which will allow you to back up your Minecraft world data while the server is running without any service interruption. The backup script creates a directory called ‘backup’ in the Minecraft server directory and copies your world data and configuration files (whitelists, banned-ips, server.properties, etc) into a datestamped directory inside the backup directory. By default, it keeps the previous 5 backups, but that can be changed by editing the mcbackup script.

Now, you can easily back up your Minecraft world data from a cron without needing to write your own script.

Version 1.1.0 of mcwrapper is available for download:

https://github.com/spikegrobstein/mcwrapper/tarball/1.1.0

See the README for details.

Automated Minecraft Server backups

Update (2011-08-30)

mcwrapper 1.4 has been released. it includes a slew of new features including backups. See other posts for more info or look at the github page:

https://github.com/spikegrobstein/mcwrapper

I’ve been running a Minecraft server off my MacMini for the past month or so and, in doing as much work as I have and being the vigilant SysAdmin that I am, it was really starting to irk me that there was no way to do proper automated backups of the Minecraft server world data.

The solution for this was that I needed to wrap minecraft_server.jar in another script that could somehow take commands as input and pass them off to the minecraft server so I wouldn’t need to run the daemon in the foreground. I wound up doing just that.

mcwrapper is the answer: https://github.com/spikegrobstein/mcwrapper

It’s got the ability to start and stop the server, which are the beginnings to getting launchd (OSX) and sysV init scripts (Linux) to enable you to treat minecraft_server.jar as a standard daemon.

Because I’m using a FIFO to communicate with the Minecraft process, you can also pipe data to the FIFO to execute arbitrary commands and script your cheats or stop Minecraft from writing to the world files while a backup process is run and start it back up when completed, thereby doing a full, automated backup without stopping the server.

See the README file for a quickstart and other details.

The software is only an alpha release right now, since I only spent about 2 hours on it already, but I believe it should be usable. As of this writing, it’s possible to start multiple instances of the server, but mcwrapper does check to make sure the server is running before issuing any commands.