Close and Go BackBack to Viget

General

GitHub Announces Pricing Plans

Ben Scofield
Ben Scofield, Development Director, March 12, 2008 3

Some of us around the Lab have been using GitHub for a while now, and we love it. (It’s currently in beta, but we’ve got some invitations if you’re interested in checking it out - just leave a comment here.) Unlike at least one of the alternatives, however, GH won’t be entirely free once it launches. Finally, we have some details on their pricing plans.

All in all, I’d say it looks very reasonable - 100 MB of space for the free account is plenty given git’s efficiency, unless you’re storing media in your repository. I also love the focus on open source projects and public repositories, which are always unlimited. I think GitHub’s clearly on the right track, and I’m looking forward to seeing how it grows.

Getting To Know Git

Mark Cornick
Mark Cornick, Web Developer, February 08, 2008 0

If you’re a developer paying attention to recent trends, it’s hard to ignore the recent surge of interest in distributed software configuration management (SCM). Many of us are familiar with “client-server” SCM systems like Subversion or CVS. Distributed SCM systems work more like peer-to-peer networks. Each developer maintains a separate, full-fledged repository. Revisions can be shared with other developers by pushing them to, or pulling them from, other repositories. You can work independently of any centralized repository (especially nice if you’re not connected to a network.) If a public repository is available for your favorite open-source project, but you haven’t gained commit rights, you can still make your own changes, track them in your own repository, and contribute patches back to the project.

Git is a distributed SCM system that has attracted a lot of attention recently. Git was written by Linus Torvalds for revision control on the Linux kernel source code, and has since been adopted by a number of projects. Several of us here at Viget Labs have tried Git recently and had much success. It’s not the only distributed SCM out there, but it’s one that we like enough to adopt for some of our work.

If you’re using an up-to-date Linux/BSD distribution or an OS X packaging system such as MacPorts, you likely have a Git package available to install - look for a package called “git” or “git-core”. If not, the Git source compiles and installs easily (unless you’re on Windows, which requires some effort we won’t get into here). From there, the Git tutorial and Everyday GIT will help get you started. For those of us who are used to Subversion, there is a Crash Course which helps you learn the Git commands corresponding to your familiar Subversion operations. (There’s even a git-svn conduit to allow you to keep a Git repository in sync with a Subversion repository, effectively allowing you to use Git as a frontend for Subversion.)

Since each developer’s working copy is a bona fide Git repository, there are multiple possibilities for working with Git. In a larger team setting, you might actually prefer an approach similar to client-server systems, where you maintain one “master” repository which each developer pulls from and pushes to. For a small team (say, two or three developers) it may be effective to have each developer pull changes from, and push changes to, each of the others directly. And if you’re a solo developer, then one Git repository on your development machine is likely all you need.

Git works well with other tools you may have in your toolbox. Git support in Rails’ code generators was recently added to edge. A Git bundle for TextMate is under way. Capistrano supports Git starting with the most recent release (2.1.0.) And if you’re using Viget’s rsync strategy for Capistrano, we’ve just updated it to work with Git. You can expect to see more support for Git in other tools as it gains popularity.

If distributed SCM interests you, give Git a try. It’s easy to get started, and quite powerful once you get the hang of it.

2007: A Development Lab Recap

Patrick Reagan
Patrick Reagan, Development Director, January 02, 2008 0

In 2007, we took a big risk on technology – after 6+ years of honing our PHP skills, we officially began switching all our new custom development efforts to Ruby on Rails.  Now that the new year is upon us, I can safely say that we’ve reaped rewards from the switch.  Though ramping up the development team (myself included) on a new technology was difficult at times, we were definitely ahead of the curve.  We had already standardized on a custom-developed MVC framework for all new client projects (we used an early version to help power one of the larger applications we’ve built) and had been doing doing Test-Driven Development for almost a year prior to the switch. 

Though we had a good basis from which to start, we didn’t go it alone.  Between formal training for the development team and our involvement with various Ruby communities, we’ve made tremendous strides in the past year.  For us, last year was our chance to both hone our technical skills and showcase our talents to a larger audience.

New Technology and Tools

Our choice of technology in 2007 gave us the ability to use a more advanced suite of tools to manage our client applications.  These are some of the highlights:


  • The switch to Rails – The framework that Rails provides has made our lives as developers much easier, and has given us the opportunity to work with Ruby every day.  We are now able to concentrate more on the business logic of our applications and no longer have to write framework code (except in those rare cases when we need to patch Rails)

  • Repeatable deployment process – Consistent, repeatable deployments had always eluded us when we were launching our PHP applications.  We were able to automate parts of it and even took a stab at creating an internal tool to get our applications out to production, but we never quite found an acceptable solution.  With the introduction of Capistrano and some custom deployment recipes, we’re now able to quickly deploy critical updates to our clients’ sites.

  • Continuous Integration – While having a well-written suite of automated unit tests allows us to quickly discover when we’ve introduced defects in the code, running CruiseControl.rb tightens the feedback loop and allows us to get back on track quickly.  We receive immediate notifications in Campfire when the build is broken or if we dip below 98% code coverage (with help from this plugin).

Community Involvement

While we had always focused on technology, it had never been a priority of ours to engage with the wider development community.  In our interactions with other Ruby developers, we were pleasantly surprised to find an intelligent, vibrant group centered around Ruby and Rails, something that we had missed out on in the past. 

We found ourselves both learning from the community and contributing our experience wherever we could:

The Result?

Our strategy for 2007 represents a huge shift in the technology we use, and the impression that we’re making on the web community as a whole.  Because of this strategy, we’ve been able to attract top talent, build bigger, better applications, and generate more interest in what we’re doing here at Viget.  In just a year, we’ve gone from being a development shop that no one has heard about, to getting name recognition at many of the events that we attend – local, national, and even international. 

I’d like to thank both the development team (Ben, Clinton, Kyle, Mark, and Megan) and everyone at Viget for making 2007 a great year.  As we continue to focus efforts on recruiting, I am confident that we’re building a great team of talented developers for this year (Justin will be joining us this month) and beyond – I’m already looking forward to what else the Viget team will accomplish together in 2008.

Testing Transactions in Rails

Ben Scofield
Ben Scofield, Development Director, October 24, 2006 3

The standard framework for testing in Ruby on Rails is a thing of beauty; there are folders to drop your unit and functional tests into right off the bat, fixtures and mock objects are expected and encouraged, and when you use scaffolding you get stubs for the common CRUD tests for free. That helps make testing less onerous for developers and, as a result, applications are better tested.

Even Rails isn’t perfect, however, and there are some situations where the testing set-up created out-of-the-box just doesn’t work so well—and, unfortunately, one of those problem situations involves database transactions.

Put simply, transactions are a way to keep your data in a valid state. Say you have a banking application that allows people to transfer money from one account to another. The code might look like this:

andy_account.withdraw(300.00)
ben_account.deposit(300.00)

If all goes well, Andy’s account is $300 lighter, while I’m $300 richer—but, what if the system crashed in the middle, after the withdrawal but before the deposit? When the system comes back up, we’d see that the $300 withdrawal has been lost to the whims of the application. Transactions represent one possible solution to this problem. They run on the database server and make sure that a set of operations either all succeed or all fail. If our current example used transactions, the failure of either operation would cause both to be rolled back, leaving both accounts as they were before the ill-fated transfer attempt.

Clearly, then, transactions can be useful. It turns out, though, that when you use transactions in your code in Rails, the tests don’t always show what you’d expect them to. The problem is that, by default, all tests in Rails are already using transactions behind the scenes (to make loading and unloading test data fixtures as fast as possible). There’s a setting in the TestHelper class that controls this: use_transactional_fixtures. You could just set that to false to fix your transaction tests, but then you’d slow down the entire test suite significantly. A better alternative is to change the setting for the cases that hold transaction tests:


class TransferTest
self.use_transaction_fixtures = false
...
end

If you have transactional and non-transactional tests in a single case, it can make sense to control this setting at an even more granular level, by separating those tests in different test cases:


class TransferTest
...
end
class TransactionalTransferTest
self.use_transaction_fixtures = false
...
end

Happy testing!

Smart Application Messaging: The Email Reflector

Patrick Reagan
Patrick Reagan, Development Director, October 06, 2006 0

When it comes to the topic of messaging in a web application, clients will often ask if they can send targeted emails to their site’s users with their preferred email client (usually Microsoft Outlook). This question starts to hint at the real functionality that a client wants.  From their perspective, they need a solution that:


  1. Aligns with their current skill sets when it comes to messaging (e.g., using Outlook as the preferred email application).

  2. Allows them to deliver customized messages to every subset of their user base.

  3. Provides dynamic capabilities so that each time a new user is added, he or she will start receiving the appropriate messages.

Let’s look at the pros and cons of the traditional ways developers have solved these problems.

Approach #1: Email Export to Outlook

Most of the time, web applications simply store and display data.  A typical reporting feature in these applications is the ability to generate an email list based on certain criteria.  Once you have access to this data in the format that you want, you can use this in the “Bcc” field in your desktop email client.

This satisfies all three conditions above; but, there are a few key areas where this falls apart:


  • Instead of easily firing off an email from their address book, clients are now forced to log into the web application, run a report, and grab the contact list – not a simple proposition.

  • If the list of emails is large enough, the risk of exceeding the maximum number of recipients increases – not something we want our clients to have to suffer through.

  • Since this is a manual process, any human error introduces the possiblity of exposing our distribution list, compromising the privacy of our user base.

If we want to reduce the possibility for human error, we can rely on our application to handle the delivery of messages.

Approach #2: Custom Messaging

Assuming our application has the reporting mechanism discussed in the first approach, it’s quite simple to tie in some basic messaging functionality.  Once the user has generated the email list, we can provide a simple interface to customize the content of the message. 

While this removes the hassle of switching back-and-forth between applications, we are still faced with some issues:


  • Any advanced features (e.g., attachments, alternate content) that the client is familiar with in their existing email application will have to be custom-built into our new web-based system.

  • Though not necessarily difficult (depending on the implementation), the client now has to re-learn how to send a message from the new web application.

If we can both leverage the client’s existing email skills and provide some dynamic capabilities, we will have a solution that addresses all three objectives.

Approach #3: The Email Reflector

When I attended the Flickr Workshop in NYC early this year, Cal discussed how Flickr gives users the ability to email photos from their existing mail clients into their Flickr account.  This got me thinking about what other features were possible with this approach.

As it turns out, this gives us the ability to send email to a dynamic list of recipients using a single pre-configured email address.

The Technical Details

At a high level, there are only three things necessary to make this work:


  1. Set up the MTA to push raw email content to a script.

  2. Gather a list of email addresses.

  3. Redirect the raw message to the list of recipients.

Let’s look at these steps in more detail.  The examples provided assume that you’re working with my sample code (provided at the end of the post).

Step #1: Set Up the MTA

In my testing, I used the installation of Qmail that we had installed on one of our Gentoo development servers.  This will work just as well with a Sendmail installation – in fact, Cal discussed using Sendmail in his example.  We basically just need to configure the email for a single user to redirect to a script.

For Qmail or Sendmail, you only need to add a single line to the .qmail or .forward file, respectively (make sure the script is at least executable by the user):

|/path/to/demo/reflector.php

This handles the messages as they come in; but, we still need to decide who will ultimately receive the message.

Step #2: Gather the Email Addresses

This is pretty simple: we just need to get a list of addresses based on certain reporting criteria. Once we have this list, we can send the original message on its way, stripping the original “To” address and any unnecessary “Received” headers before we send.

Step #3: Send the Message

Using the provided EmailReflector class, we can push off all the heavy-lifting to it with just a few lines of code:

$reflector = new EmailReflector(’smtp-host’);
$reflector->setInputSource(’php://stdin’);
$reflector->redirect($recipientList);

The message is now Bcc’d to the specified list of recipients with all the original contents (including attachments) in place.

Enhancements

Because this is still “proof-of-concept” code, there are some issues that still need to be addressed:


  • Security - If someone can guess the target email address for the reflector, he or she has the ability to spam your site’s users.  By making the target email harder to guess (good) or having the sender provide a security token (better), we can minimize this risk.

  • Batching - As a site’s user base grows, the number of emails that will be sent through this sytem increases.  By providing some basic batching features, we can handle a larger volume.

  • Catch-all addresses - A reporting feature that I see as useful would give users the ability to generate a report and save it with an associated email address.  Any time a message is sent to this address, it will regenerate the report and send the email.  Setting up a catch-all email address for a subdomain would make this possible.

The Code

Download the source (.tar.gz format)
Download the source (.zip format)

A Development Community for Viget Labs and Beyond

Every team member here at Viget Labs strives to be an innovator. We members of the development team are no different - that's why we're constantly engaging in community discussions and exploring the unknown that is the next generation of open-source web applications.

Viget Is Hiring!

Viget has job openings for Ruby Developers, Interns, and Front-End Developers. Learn More »

Recent Comments

I think that polymorphic_url(@commentable, :anchor => “comment_#{@comment.id}") should work. You can also refactor the “comment_#{@comment.id}” to a separated method, like dom_id, which returns the dom identifier of the comment.