Pivotal Labs

Main menu

Skip to primary content
Skip to secondary content
  • About
  • Case Studies
  • Team
    • Executives
    • Locations
      • San Francisco (HQ)
      • Boston
      • Boulder
      • Denver
      • London
      • Los Angeles
      • New York
  • Community
    • Blogs
    • Tech Talks
    • Events
  • Careers
    • Lifestyle
    • Principles & Practices
    • Benefits
    • FAQ
    • Apply
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

Monthly Archives: July 2009

Christian Sepulveda

Tweed Update: v0.9.8

Christian Sepulveda
Thursday, July 9, 2009

A new version of Tweed is available! (v.0.9.8)

Bug Fixes

  • memory leak with notifications
  • timeline marker not being preserved when Load More is tapped
  • loading spinner hanging when minimizing during a load
  • preserve tweet position on refresh
  • tweets not always displaying after Load More
  • false notification reports
  • removed Refresh and Load More from conversation timeline
  • notifications stopped when swiping away dashboard with Tweed closed

Features

  • simplified notifications: when enabled, they check every 15 minutes, independent if Tweed is open or closed
  • configure notifications: selectively configure timelines
  • Tap header: option to jump to top/bottom of timeline
  • When loading a timeline, start with marker (if present)
  • load up to 200 tweets when a marker is present (100 tweets for searches)
  • notifications: display badge counter number of timelines with notifications
  • notifications: dashboard stack allows users to cycle through all notification timelines

Coming soon…

  • photo integration (via auto generated email) — this week
  • configure notifications for bookmarks
  • *

Let us know your feedback either @tweed on Twitter, tweed-support@pivotallabs.com or http://tinyurl.com/satisfaction-tweed

Tweed

Tweed

Tweed

Tweed

Tweed

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

How to make Firebug 1.4 behave sanely

Pivotal Labs
Monday, July 6, 2009

As has been noted a few times, the new activation model in Firebug 1.4 is kind of psychotic. The main problem seems to be that the Firebug developers have disconnected the formerly linked concepts of “open” and “activated” for a few reasons that make sense to the developers, but make no sense to the users. Unless you’ve really internalized how Firebug works under the hood (and there are probably a few dozen people like that in the world), Firebug now seems to randomly choose whether it’s going to be open or closed when you visit a page. Not fun.

The workaround that we’ve found is to force firebug to be active on all pages. You can do this by right clicking the Firebug icon in the bottom right and checking “On for all web pages”. This makes Firebug behave mostly like the old way where the panel would stay open as you browsed around until you closed it. The big caveat is that it only stays closed if you use the firebug icon in the bottom right of your window, not the close panel button.

On for all web pages

This will slow your browser down a lot on ajax heavy sites like Pivotal Tracker or Gmail. You can get around that to a certain extent by disabling the Net tab on those domains, which will keep it from displaying every XHR request.

disable net panel

Hopefully this helps, and hopefully the Firebug 1.4 final release has a saner activation model…

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Using assert_select and friends in Helper Tests

Pivotal Labs
Monday, July 6, 2009

Assertions such as assert_select, assert_tag, and css_select are powerful tools in view tests. Since view helpers generate a chunk of HTML, it is sometimes practical to use these assertions to test their return value.

If you attempt to use assert_select it will fail because there has not been a call to render, as is done in a view test. To get around this you can store the result of the helper method in @response.body. Once @response.body is populated, the assertions will work like expected.

Update: For people using RSpec, Pat Maddox posted a helpful suggestion in the comments showing how to use have_tag to accomplish the same thing in RSpec style.

Example

describe TagsHelper do
  describe "#tag_list"
    describe "when the user is not an admin"

      it "should not have links to delete the tags" do
        @response.body = helper.tag_list
        assert_select "a", 0
      end

    end
  end
end

Reality Check

If you find yourself writing a helper method that generates a lot of HTML, or is overly complex, stop and ask yourself whether it would be more appropriate to move this code into a partial.

Attribution

Credit for this tip goes to a comment by Bill Siggelkow on the Nuby on Rails blog.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

The Engine Yard Cloud: A Programmable Deployment Platform

Monday, July 6, 2009 | Run time: 58:12

Ezra Zygmuntowicz of Engine Yard details their new Flex cloud hosting product, including the extensive use of Chef for automated deployment. Ezra also discusses the feature roadmap for Flex.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Abhijit Hiremagalur

Standup Blog 02/07/2009: RM 1.1.1 + Java 1.6 on OS X Solved, Pivotal video, PDF Libraries

Abhijit Hiremagalur
Monday, July 6, 2009

Interesting Things

  • Answer to RM 1.1.1 + Java 1.6 on OS X issues
  • Pivotal/EngineYard video

Help

“What Ruby PDF libraries are people using?”

  • Especially for HTML to PDF generation
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Introducing ActiveApi – A sane way to translate your data to xml

Pivotal Labs
Sunday, July 5, 2009

ActiveApi allows you to define a schema in Ruby, and use that schema to convert ruby objects to xml. An example looks like this:

Schema.version(:v1) do |schema|
  schema.define :article do |t|
    t.attribute :id
    t.string :title
    t.date :published_on
    t.has_many :comments
  end
end

On one of the apps I’m working on now, we have to expose our data as xml. This XML will be used as the datasource for reports, and as a way for external clients to import data into a data warehouse. The clients who will be importing the data are enterprisey – they have lots of tools that work with DTDs and XSD’s, and they’ve never heard of ActiveResource. (Many barely know what Rails is.)

On this app the data model is quite large and complex, and changes will be inevitable. We may want to generate reports using the latest and greatest xml, but some clients may take longer to update their data import code, so it’s very likely that we’ll have to maintain overlapping versions for short periods of time.

Through this process I’ve come to think that exposing your data via XML is not the job of the model. Instead, it’s the job of a separate class that is specifically designed to translate your model schema into a schema appropriate for public consumption.

A good api tool will have built-in support for:

  • XSD or DTD generation
  • Versioning
  • The ability to represent your model in a way that is not tightly coupled to the model itself – so you’re models can change at a different rate than your xml schema

ActiveApi attempts to provide this functionality.

Installation

sudo gem install zilkey-active_api

Usage

You define a schema like so:

Schema.version(:v1) do |schema|
  schema.define :article do |t|
    t.attribute :id
    t.string :title
    t.date :published_on
    t.has_many :comments
  end

  schema.define :comment do |t|
    t.belongs_to :user
    t.string :article_title, :value => proc { |element|
      element.object.article.title
    }
  end

  schema.define :user do |t|
    t.string :username, :value => :user_name
  end
end

To create xml from this schema, you could write code like this:

ActiveApi::Schema.find(:v1).build_xml(@articles, :node => :article).to_xml

Which will give you xml output that looks like this:

<?xml version="1.0"?>
<articles>
  <article id="1">
    <title>target efficient applications</title>
    <published_on>2004-08-22</published_on>
    <comments>
      <comment>
        <article_title>target efficient applications</article_title>
        <user>
          <username>foo</username>
        </user>
      </comment>
    </comments>
  </article>
  <article id="2">
    <title>recontextualize viral e-services</title>
    <published_on>2004-12-05</published_on>
    <comments>
      <comment>
        <article_title>recontextualize viral e-services</article_title>
        <user>
          <username>foo</username>
        </user>
      </comment>
    </comments>
  </article>
</articles>

Extending

ActiveApi is highly extensible. The general pattern used to extend ActiveApi is to subclass the default ActiveApi implementation, and specify that you’d like to use your subclass instead.

For example, if you are working with a database that has audit columns such as timestamps, you might want to do this:

class MyDefinitionClass < ActiveApi::Definition
  def timestamps
    date_time :created_at
    date_time :updated_at
  end
end

@schema = Schema.version(:v1, :definition_class => MyDefinitionClass) do |xsl|
  xsl.define :article do |t|
    t.timestamps
  end
end

Schema.find(:v1).build_xml([@article], :node => :article).to_xml

Which will produce the following xml:

<?xml version="1.0"?>
<articles>
  <article>
    <created_at>1945-12-21T00:00:00+00:00</created_at>
    <updated_at>1992-04-05T00:00:00+00:00</updated_at>
  </article>
</articles>

NOTE: when specifying custom definition classes, those classes must be loaded before calling Schema.version

You can also create custom classes for any element you define, like so:

@schema = Schema.version(:v1) do |xsl|
  xsl.define :article, :builder_class => "MyCustomClass"
end

class MyCustomClass < ActiveApi::ComplexType
  def build(builder)
    builder.send :foo, :bar => "baz" do |xml|
      xml.send :woot, "lol"
    end
  end
end

Schema.find(:v1).build_xml([@article], :node => :article).to_xml

Which will produce the following xml:

<?xml version="1.0"?>
<articles>
  <foo bar="baz">
    <woot>lol</woot>
  </foo>
</articles>

NOTE: since the builder classes are evaluated at runtime, you can specify a string name for the class, and the class does not have to be loaded before calling Schema.version

Features

You define your schema completely separately from your data. So you could in theory render multiple types of objects with the same schema, provided that they have the same interface. You could also render a single object in any number of ways.

You can choose to have the builder send methods on your object, or provide more complex values by using the :value => proc{} syntax. Since you can define the value of the elements separately from the names, aliasing your objects field names is built in.

The element keeps track of all of it’s ancestors, so you can access objects that were rendered as ancestors, even if those objects aren’t ancestors in your object graph.

The Schema definition just creates an array of Ruby objects, which you could use to create documentation or XSD files. One of my major goals for this gem is to create valid XSD from the schema itself. Given how extensible it is, I’m not sure how that will work yet, but I’m psyched to give it a shot.

You define your schema versions using whatever versioning scheme you want – could be a string, symbol or any other object. You can render the same objects with different schemas easily. This library is totally agnostic as to how or if you version your schemas – but if you decide to version, it makes it easy.

The schema defining DSL allows you to define any valid XSL data format – it formats dates, times and datetimes in XSD compliant formats, it URI escapes any element tagged as anyURL and has helper methods for all XSD data types in both their native form (anyURL) and a more ruby-friendly form (any_url) – so you can write:

  schema.define :article do |t|
    t.anyURL :foo
    t.any_url :foo
  end

And they will be emitted identically.

ActiveApi also allows you to define polymorphic relationships via the XSL “choice” instruction:

      xsl.define :comment do |t|
        t.belongs_to :commentable, :choice => {
          "Article" => :article,
          "User" => :user
        }
      end

This allows your API to determine which elements to render at runtime, while still giving you complete control over the schema to use for that element. This allows you to have more than one representation of your objects – one that gets rendered if the object is the root, and a different one that gets rendered if it’s being rendered as a sub-element of another object.

Integration with Rails

ActiveApi is framework agnostic. While the belongs_to / has_many syntax is Rails-like in name, it does not depend on ActiveRecord. It also does not modify or interfere with AR in any way. To use xml generated from ActiveApi in a controller, you can do this:

def index
  @articles = Article.all

  respond_to do |format|
    format.html # index.html.erb
    format.xml  do
      render :xml => ActiveApi::Schema.find(:v1).build_xml(@articles, :node => :article)
    end
  end
end

Implementation

ActiveApi uses’s Nokogori::XML::Builder to create the xml nodes. As such, the creation of the xml is fast. The rest of the code likely needs major refactoring to be performant and have a small footprint with large datasets. In particular, it creates a new object for every collection, element and value. That’s a lot of objects. I’d love to hear any comments about how to improve this aspect of the design.

Authors

While I wrote all of the code in this repo, the code was inspired by pairing on a similar project with:

  • Mike Dalessio
  • Peter Jaros
  • Ben Woosely

Development

http://github.com/zilkey/active_api/tree/master

See the issue tracker on github for the list of features and bugs I know about.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Use Autospec to Your Advantage

Pivotal Labs
Saturday, July 4, 2009

I like Autotest because it allows me to stay within my code editor and let my test suite run automatically in the background. After each run I get a nice, unobtrusive, growl notification informing me whether my most recent change caused the tests to fail or pass.

It used to be that setting up and configuring Autotest for the OS X with pretty growl notifications was a nontrivial task. I remember that I spent several hours getting it working a year ago. However, there has been several developments with Autotest in recent months that greatly simplify the process. One of those enhancements is that Autotest can now use FSEvent introduced in OS X Leopard so that it no longer has to continuously poll the filesystem. This has the advantage of vastly reducing Autotest’s CPU usage when idle.

Install Autotest

To setup Autotest on a Mac I recommend following this nice, up-to-date, walkthrough on the Viget Labs Blog.

Using Autotest with RSpec

Complete instructions for Autotest integration with RSpec are described on the RSpec wiki. The gist of it is this:

Add an initialize hook to Autotest

Place the following code snippet in a file called .autotest in the root of your Rails project:

Autotest.add_hook(:initialize) {|at|
  at.add_exception %r{^.git}  # ignore Version Control System
  at.add_exception %r{^./tmp}  # ignore temp files, lest autotest will run again, and again...
  #  at.clear_mappings         # take out the default (test/test*rb)
  at.add_mapping(%r{^lib/.*.rb$}) {|f, _|
    Dir['spec/**/*.rb']
  }
  nil
}

Start Autospec in Terminal

RUBYLIB=./lib RUBYOPT=-rubygems AUTOFEATURE=true autospec

To avoid typing or remembering this cumbersome set of options to start autospec, I added it as an alias to my bash environment.

alias autospec='RUBYLIB=./lib RUBYOPT=-rubygems AUTOFEATURE=true autospec'

Autotest Alternative

For using Autotest with RSpec there is also the RSpactor gem which touts advantages homogeneous to those provided by the new autotest-fsevent. I have not tried RSpactor yet. If you do be sure to check out the RSpactor wiki as there is no README on Github.

Notes

  • I do not recommend using Autotest/Autospec with RubyMine. The auto save feature of RubyMine would cause Autotest to run incessantly.
  • Sometimes autospec seems to hang after running for a while and stops detecting that a file has changed. When this happens I send a SIGINT to the process by pressing CTRL+C. This causes autospec to reload and run the entire test suite.
  • To kill autospec press CTRL+C twice.
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Christian Sepulveda

Tweed: Preview of v0.9.8

Christian Sepulveda
Saturday, July 4, 2009

Bug Fixes

  • false notification reports
  • timeline marker not being preserved when Load More is tapped
  • loading spinner hanging when minimizing during a load
  • preserve tweet position on refresh
  • ….

Features

  • configure notifications: individually turn on/off DM, home, replies
  • Tap header: option to jump to top/bottom of timeline
  • When loading a timeline, start with marker (if present)
  • a few more….

We expect this release to hit App Catalog early part of this week, July 6.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Christian Sepulveda

Tweed: Photo Upload Update

Christian Sepulveda
Friday, July 3, 2009

As discussed in the last release notes, the Palm Mojo SDK doesn’t provide a general mechanism for uploading photos. However, email supports attachments, so you can email photos from the phone.

We started to develop an intermediary service that would accept emailed photos, then upload these to TwitPic, TweedPhoto, etc., and return the urls to Tweed. Then Tweed could post to Twitter with the photo links.

Unfortunately, this takes more time than we would like. (There are latency, scalability and general reliability issues.)

So, we are going to start with a much simpler option — the Compose Tweet screen will create an email on behalf of the user for posting tweets via photo services that support email. (Tweed will have a preference for storing the email address/pin for the service the user chooses.)

There are some issues with this simplified solution:

  • “in reply to”/conversations will not be supported
  • no DM support
  • in simple terms, email tweet posts are just posts, not replies

We will have this solution later this week.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Pivotal Labs

Becoming more flexible

Pivotal Labs
Wednesday, July 1, 2009

Our friends at Engine Yard have just launched the beta of their new cloud hosting product, Flex. If you’re familiar with their Solo product you’ll find Flex to be pretty similar, just more… flexible. Where solo lets you run your Ruby on Rails application on an Engine Yard stack on an Amazon EC2 instance, Flex lets you run it on a cluster of EC2 instances.

In the last month I’ve put a handful of applications up on Solo, mostly demo or staging servers for doing story acceptance and release testing. Solo is great for that. After you’ve gone through the setup process once, you can easily spool up a server for a few hours when you need it on just a few minutes notice, then turn it off when it’s not needed anymore. Flex gives you that same kind of adaptability, allowing you to add instances to your cluster to match traffic demands as needed.

Last week I got my first production application running on Flex. The Pivotal Labs company website is now hosted on Flex, and it’s humming along quite nicely. There were a few rough spots to work through since we were working with a pre-release product, but I’m pretty happy with our setup now. Since Flex is new, I thought it might be useful to share some of the things my fellow pivots and I learned getting things running there.

It turns out the trickiest bit for us was converting some rather intricate URL rewrite rules from Apache to Nginx. Yes, Flex and Solo support Apache, but we’ve been moving to standardize on Nginx so it was worth a bit of fiddling. My point is, the hardest part had nothing to do with Flex itself.

Now, about Flex. If you haven’t checked out Solo yet, there are some things that are different from your standard Engine Yard deployment, or most other deployments even. For starters, your server config has to be something that can be started and stopped and restarted. There are two or three parts to how that works. The base system (OS + packages) is created from an image and configured using Chef. The database has its own storage and uses an Amazon EBS volume for storing snapshots. The Rails application and some system config files (everything under /data) are on a separate EBS volume. Keeping snapshots on EBS means it’s easy to restore an instance.

Setting things up is fairly easy but takes a few steps. Each instance is assembled from an environment, application, IP address, SSL certs. I don’t want to do a full tutorial here, but just want to give some context and an idea of the level of complexity. Going through all the steps in the control panel to configure an instance takes only a few minutes. I can set up a new application now in about 10 minutes if I’m not doing anything tricky with multiple virtual hosts. If you want to see how it works in detail, check out the Getting Started page for EY Cloud.

There are a few configuration options where you’ll probably end up wondering how to decide which to pick. Some of these will affect how much you pay so you should make sure you are working within your budget, but here’s what I’d recommend.

  • Availability Zone: the default is probably fine. If you care about this you probably know enough for how to choose.
  • Instance Size: 1.7GB RAM / 5ECU / 32bit – this gives good performance and the best value for your dollar. This is similar to a 2 core 2.3 GHz server.
  • Storage Volume: 5GB – the default size is probably fine. All you’re storing here is your app code and static assets. You probably want to put any uploaded files on S3 instead of storing on EBS.
  • Database Volume: ??? – this is the MySQL file system and needs space for the storage for your database. Pick a size that’s large enough for your requirements. 5GB is probably fine for small apps, but I’ve seen much, much larger.

By the way, EBS volume snapshots are stored on S3, so you’ll be paying for storing them as well.

As I said, converting the web server config from Apache to Nginx was a pain, but that’s not typical. Aside from that, there are a few things to adjust to. The biggest is that in many cases you may not need to use Capistrano to automate your application deployment. If your application code is in a git repo, all you need to do is supply a URL and set up the deploy key. The Chef deploy scripts will take care of pulling down the code, creating symlinks, running migrations, and managing restarts of Mongrel or Passenger. If you require extra steps, you can add ruby files to your project that run at several hooks (before migration, etc). Or you can use Capistrano, which is what we did for this site. We had a fairly standard eycap based deploy setup, and it only took a few minutes to convert it to deploy to Flex. If you do opt to use Capistrano, you want to make sure when you click the deploy link in the control panel to uncheck the options to deploy the code and run migrations.

You won’t be able to run sendmail on your Flex server, so you’ll need to find a SMTP service to use to send email from your application. You can run a SMTP server on your own box somewhere else, or you can use a 3rd party service. We’re using authsmtp.com and that’s working fine, but I wasn’t involved in that choice so I can’t say much about why we chose them.

Flex/Solo let you specify the rubygems your app needs in the control panel, but I don’t like that solution. It’s hard to manage and keep up to date. We have our apps set up using geminstaller. Once you have your gems listed in config/geminstaller.yml you only need to add the geminstaller gem in the control panel. We added a hook in deploy/before_migration.rb to run geminstaller and everything works fine now. I suppose you could do something similar using the config.gem and rake gems:install, but I’ve found that pretty fragile for installing gems (go ahead, mention a class defined in a gem in your environment and see what happens).

New products always have a few rough edges and Flex is still getting polished. There are a couple areas I’m eager to see improvement on. One is how system configuration files are managed – the current approach for keeping modified files by tweaking their names is an interim solution and isn’t very user friendly. I’m also looking forward to more flexibility in customizing the chef scripts, and API access for configuring instances instead of going through the GUI for everything. It would also be nice to have a way to manage sensitive files you don’t want to store in your code repo, like S3 key files.

Flex is a nice solution for easy scalable deployment, even considering it’s a beta release. Engine Yard is already aggressively working on addressing all of the issues I’ve encountered with the system, and then some. Congratulations to them on a compelling new product.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Topics

  • agile (778)
  • rails (113)
  • testing (87)
  • ruby (83)
  • ruby on rails (70)
  • jobs (62)
  • javascript (54)
  • techtalk (44)
  • rspec (38)
  • activerecord (29)
  • productivity (29)
  • gogaruco (29)
  • ironblogger (29)
  • git (28)
  • nyc (27)
  • rubymine (25)
  • mobile (22)
  • bloggerdome (21)
  • cucumber (20)
  • process (19)
  • pivotal tracker (19)
  • jasmine (19)
  • design (18)
  • ios (18)
  • webos (17)
  • objective-c (17)
  • android (16)
  • palm (16)
  • "soft" ware (16)
  • fun (15)
  • tracker ecosystem (15)
  • ci (15)
  • cedar (15)
  • rails3 (14)
  • performance (14)
  • bdd (14)
  • gem (13)
  • tdd (13)
  • selenium (12)
  • css (12)
  • goruco (12)
  • bundler (12)
  • meetup (11)
  • railsconf (11)
  • nyc-standup (11)
  • capybara (10)
  • mac (10)
  • mojo (10)
  • chef (10)
  • api (10)
Subscribe to Community Feed
  1. ←
  2. 1
  3. 2
  4. 3
  5. 4
  6. 5
  7. →
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Contact
  • Labs
  • Events

Contact Us

contact@pivotallabs.com
+1 415-77-PIVOT
TwitterLinkedInFacebook

Pivotal Tracker

Tracker is the award-winning agile project management tool that enables real-time collaboration around a shared, prioritized backlog.
Visit pivotaltracker.com >