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
Ryan Spore

Get your volunteering hand ready

Ryan Spore
Tuesday, August 14, 2012

Helps

  • Nesting separate rails apps

What’s the best way to do a request test against another rails app in a separate directory?

We want:

  • not to deal with separate processes
  • to be able to use nice capybara test matchers (i.e. visit “/other_service/foo” and page.should have_content(”other service title”) )
  • for it to work on CI well

Should we use a Rack middleware?

Capybara Servers and Pow seemed like good solutions, Engines not so much. Also trying to run integration tests with the adaptors and stub adaptors in other tests.

Events

  • Today’s Tech Talk: The Psychology Behind Pair Designing

Folks from the outside can register on EventBrite to come. Lunch is included.

There will be opportunities to get up on stage and pair live with Karl.

Summary:
More design clarity. Less redesign time. What if methods like Pair Design could increase the efficiency of your team and the quality of your products? Karl Dotter will explain his hypothesis on Pair Design, how he is helping teams practice pair design to build great products and what to do to start practicing pairing with members of your team. You’ll also find out how to participate in P.A.I.R (Pairers Against Inefficiency and Rework), a fun research program he’s working on which will help quantify the benefits of Pairing.

  • eXtreme Tuesday

Weekly eXtreme Tuesday returns again! 6:30 in the presentation space.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Matt Royal

SF Standup – Left Handers Day

Matt Royal
Monday, August 13, 2012

Interestings

  • Be sure to close your connections inside an Enumerator

Since the block in an Enumerator has its own Thread context and thus connection, be sure to close it at the end od the block.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Will Read

Postgres features n’ bugs

Will Read
Wednesday, August 8, 2012

Interestings

  • Potential Heroku/PG/hstore bug in 9.1.3

One of our tables was using an hstore to collect data (a really big json object). We discovered that the primary database on staging was using PG 9.1.3 while our acceptance & production apps were using 9.1.4. Pushing this very large (58K) object into the hstore caused a Postgres failure:

ActiveRecord::StatementInvalid: PGError: ERROR: cannot execute INSERT in a read-only transaction : INSERT INTO “xxxx” (”created_at”, “data”, “updated_at”, “user_id”) VALUES ($1, $2, $3, $4) RETURNING “id”

while saving the same data into our acceptance app did not cause the error.

We suspect that there is a bug in PG 9.1.3 when inserting “big” strings into an hstore that is fixed in 9.1.4.

We promoted a new 9.1.4 db on our staging app. This cleared our problem.

  • postgresql_cursor and streaming in rails

We were able to stream the contents of a table to the user without loading the whole dataset into memory.

  • RubyConf CFP ends Friday

It’s in Denver this year.

https://rubyconf2012.busyconf.com/proposals/new

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Brandon Liu

New Jasmine Gem

Brandon Liu
Friday, August 3, 2012

Helps

  • New Jasmine Gem

There’s a new version of jasmine-gem on GitHub – please test it out so we can push a new gem next week.

https://github.com/pivotal/jasmine-gem

  • jQuery opacity

Once the CSS opacity is set on an element with jQuery the z-index is no longer respected and the element appears on the bottom.

Leads:
Can it be reproduced in other browsers? Only tried Chrome so far.

Interestings

  • Safari doesn’t like Rails timestamps

my_model.created_at or my_model.create_at.to_i spit out values that when you (in JavaScript) new Date(value), give crazy dates in Safari.

The workaround is to use:

(Ruby)
value = my_model.created_at.to_f * 1000

(JS)
date = new Date(value)

Discussion:
Try all browsers when dealing with a Date API
There’s also DateJS, but has not been maintained in a long time.

  • Jasmine failed to start on latest Chrome

If you have an updated version of Chrome and jasmine fails to start Chrome, reinstalling later version of chrome driver (http://code.google.com/p/chromedriver/downloads/list).

Or alternative is to re-image the machine, which contains later Chrome and later ChromeDriver.

  • bitbucket Tracker integration broken by ‘&’ in author name

We spent several hours tracking down this (open) bug in bitbucket’s tracker broker. You can change the ampersand to something else in your git-pair script.

  • IE9 svg path click handler

IE9′s click handler for SVG paths treats two clicks as a single click and six clicks as a double click.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Dan Podsedly

Velocity Matters

Dan Podsedly
Wednesday, August 1, 2012

Last week, we made a slight tweak to how velocity is calculated in Pivotal Tracker, to handle team strength overrides in a simpler, more explainable way. As a result, if your project has an adjusted team strength in a recent iteration, you may be seeing a slightly different velocity.

Details of how velocity is calculated, and how team strength affects it, are at the end of this post.

This seems like a good opportunity, though, to step back a bit, and revisit the velocity concept in Tracker and why it (still) matters. Read on, even if you’re an old hat to agile and Tracker!

What is Velocity?

First, let’s re-define what velocity is. Christian Niles, our iOS engineer, recently gave it an eloquent description (inspired by his recent relaxed strolls through the streets of Paris):

“Just like a speedometer that measures how fast you’re hurtling through space, Tracker’s velocity is a measurement of how fast your team completes stories. Instead of miles or kilometers per hour, Tracker expresses velocity as the number of points completed per iteration.

Because Tracker stories are assigned point values instead of due dates, Tracker calculates velocity by averaging the number of points you’ve completed over the past few iterations. In Tracker, past predicts future.”

It’s About the Conversation

Yes, velocity does give you a glimpse into the future, in the form of more realistic estimates of when milestones will be hit, at least compared to wishful due dates. It’s obviously just an approximation, though, and the velocity number itself is ultimately not very meaningful outside the context of a given project.

What’s really valuable are the conversations that story estimation encourages within development teams (and their product owners). Conversations that uncover all kinds of assumptions and hidden scope, and give the product owner the insight to make value decisions at every step (is that 5 point feature really worth it, is there a simpler alternative?), which all leads to leaner, better product, and a more direct path to the finish line.

Having a crisp, prioritized backlog of estimated stories, and a steady velocity, lets you have really constructive conversations with your stakeholders when facing that inevitable change to requirements. Dragging those new stories into the backlog gives you immediate feedback about how the scope increase will affect the future timeline and planned releases, and allows you to make tradeoff decisions (“ok, let’s move these other stories down so we can still make that milestone”).

These conversations are where all the important tactical decisions are made, and there will be many, as you keep learning as a team, and the world keeps changing on you. Each one takes you closer and closer to winning the battle (and shipping great software).

Consistency is Everything

Steady state allows you to predict, at least roughly, when your project will hit important milestones. This gives your business the ability to plan ahead and to make meaningful tradeoff decisions (usually scope vs time), as you discover more scope (and you always do). Predictability is rare in the software industry, and only comes when you get your project to that zen-like state of steady, consistent pace, measured by low volatility (of velocity).

Achieving low volatility takes an ongoing effort, but the practices that collectively yield it are worth the effort on their own merit. Break down large features into small stories (that fit into a single iteration), estimate as a team, maintain a constant ratio of features to bugs and chores every iteration, deliver stories continuously, and have your product owner highly involved, available, and accepting those stories daily.

Managing Team Fluctuations

Unless you’ve got a team of cyborgs, or perfected cloning technology, chances are there will be weeks when a big subset of the team is sick (yes, that achilles heel of pair programming), on vacation, at a conference, or it’s just the usual between the holidays lull with a skeleton crew.

The team strength feature allows you to plan for that (or account for it retroactively), in terms of velocity. For example, if half of your team leaves for a conference one iteration, you might set your the team strength of that iteration to 50%. Likewise, if your team works all weekend to prepare for launching your product, you would set the team strength to 140% (since they worked 7 days instead of a normal 5 day work week).

Check out a short video on team strength here.

You can also adjust the length of a single iteration, for situations such as the big end of year holidays. Or you can use it to effectively put your project on hold, by combining iteration length override with a team strength of 0%.

Just the Formula, Please

How velocity is calculated is fairly straightforward, it’s the sum of all ‘normalized’ points completed over a given set of iterations (based on project settings), divided by the combined length of all those iterations, in weeks. ‘Normalized’ points are the number of points the team would have completed in an iteration at 100% team strength.

velocity_per_week(iteration_1, ..., iteration_N) =
    SUM(iteration_i.points / iteration.team_strength) /
    SUM(iteration.length_in_weeks)

Iterations with a team strength of 0 are excluded from both sums.

The formula above always returns velocity per week. The project velocity Tracker displays is always multiplied by the default iteration length, and rounded down to the nearest integer. For example, if your iterations are 2-weeks long by default, Tracker will multiply the per-week velocity by 2.

Learning More

We’ve got quite lot of detailed information about velocity and related topics in the Tracker FAQ, as well as the Getting Started guide. In particular, take a few minutes to watch the Introduction to the Concepts video.

If something still isn’t clear, give us a shout!

p.s. thanks to Richard Jones for the awesome Millenium Falcon pic. we want one!

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Brandon Liu

Like Dreamcatcher, but for Shapes

Brandon Liu
Wednesday, August 1, 2012

Helps

  • capybara-webkit save_and_open_page returns empty DOM after AJAX request

Investigate:
Use page.driver.render to save a screenshot.
Look at capybara issue discussed yesterday at http://pivotallabs.com/users/abruce/blog/articles/2220-rager-party-standup-7-31-12-

Interestings

  • Shapecatcher: draw something, find the closest-matching Unicode character

http://shapecatcher.com/

Also of note: http://nice-entity.com/

  • bundle exec foreman

Using bundle exec may solve some Foreman issues teams have been seeing.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Andrew Bruce

Rager Party (Standup 7/31/12)

Andrew Bruce
Tuesday, July 31, 2012

Helps

  • New Mail Rack

There’s a new mail rack near the lockers.

  • Capybara inconsistent about what page it’s on

We have a spec that does something along the lines of

visit '/#foo'
visit '/#bar'
save_and_open_page
page.should have_content("bar")

The save_and_open_page gives the bar page, but the assertion fails because it looks for "bar" in the contents of the foo page rather than the bar page.

One suggestion was to tell capybara to resync.

  • Webviews for iOS app – slow?

One team was worried about the speed of Webviews versus the speed of e.g. mobile Safari. It was suggested to try it and see, benchmark even.

Interestings

  • Mad at your Rails logs? Try Lograge

https://github.com/roidrage/lograge uses the amazing notification system in Rails 3 – which itself is worth a read – to make more useful logs for staging & production environments. Looks like it came out of the TravisCI project. And if you’re logging to Splunk, this is more like what you want.

  • Jasmine busted after Firefox upgrade?

Upgrade the selenium-webdriver gem to 2.25.0 and happiness will prevail.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Brandon Liu

SF Standup 7/30

Brandon Liu
Monday, July 30, 2012

Helps

  • Apache proxy: (502)Unknown error 502: proxy: pass request body failed

We need to make requests to a server and these requests have to come from a fixed IP address and be authenticated via SSL. For this purpose we set up a EC2 instance to function as a proxy. We can make cURL requests using our key and certificate from the proxy machine successfully. But when we go through Apache we get:
“(502)Unknown error 502: proxy: pass request body failed”

Interestings

  • Backbone’s views’ $el contains all matched elements

If you initialize a Backbone view with an el selector that matches more than one element: within the view $el will refer to a jQuery collection that contains all the matched elements, while el will contain the DOM object for only the first element matched. To achieve consistency, you might want to instantiate your view like so:

new view({el: '.selector_that_matches_many:eq(0)'});
  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Joe Moore

How We Use tmux for Remote Pair Programming

Joe Moore
Tuesday, July 17, 2012

Update 07/18/2012: We have added tmux-vim autosaving support as a Vim plugin. It’s available here: https://github.com/pivotal/tmux-config

Update 07/20/2012: There is a lively discussion on Hacker News about this post in addition to the comments below.

tmux is the cool kid on the block for remote pair programming, as long as you are using a terminal based editor such as Vim or Emacs.

There is no shortage of tutorials and guides regarding how to use tmux, thus my only introduction to tmux will be this: tmux is a terminal multiplexer and supports shared terminal usage.

Our large software project used tmux regularly for remote pair programming and settled on a configuration that has worked well for our team. Read on to learn about tmux’s advantages and disadvantages vs. desktop screen sharing, why and how we used it, and how we addressed the many challenges of remote pairing using tmux.

Advantages vs. Desktop Screen Sharing

  • Fast! tmux has the least latency of any collaborative code editing we have used
  • Addictive usage model: tmux’s multiple terminal pane usage model is very handy in general. Some of us now use tmux even when we are not remote pairing
  • No extra heavyweight software: if you have tmux and ssh access you’re good to go

Disadvantages vs. Desktop Screen Sharing

  • Requires ssh access and thus possibly a VPN
  • Extra overhead of learning and using tmux commands
  • Lack of desktop friendly UX, such as mouse support, function keys, ⌘ key
  • Only for terminal based editors, such as Vim and Emacs
  • Might still need desktop screen sharing for GUI-based tools and tasks: shared web browser for web development, etc.

Why We Used It for Remote Pairing

Due to network latency GUI-based desktop screen sharing was intolerably slow for coding. tmux made network latency a non issue. My personal experience was that tmux + Vim was so fast when working remotely that it was usually indistinguishable from coding locally.

Monitor Setup

We use two monitors: the iMac’s main 27″ monitor and a large (usually at least 24″) LCD rotated vertically.

We usually had iTerm running a shared tmux session on the large 27″ display and a desktop screen sharing session on the vertical display. The vertical display usually had the shared web browser visible since we were usually doing web development.

Challenges and How We Addressed Them

Most of our in-office developers only used tmux when remote pairing: the majority of their development was in-person pair programming using MacVim and “normal” tabbed iTerm. The occasional switch to terminal-based Vim within tmux and a bunch of tmux terminal panes was the most challenging aspect of using tmux as part of our development stack. The major difference were:

  • Automatic saving within MacVim was lost
  • No mouse support
  • Scrolling onerous in tmux
  • Copy-paste actions onerous in tmux
  • MacVim keymapping not fully supported in terminal Vim
  • Learning tmux specific commands

Read on to see how (or if) we addressed the above challenges.

Automatic Saving

Once you have automatic saving it’s tough to give it up. Our buffers automatically saved whenever MacVim lost focus. After quite a bit of work we were able to add automatic Vim saving support within tmux. It’s not as good as MacVim’s autosave, but it’s pretty close. Please see this Github pull request for how to set up automatic saving. (Note, I’ll update this post as the pull request progresses.)

Update 07/18/2012: Our tmux-vim automatic saving Vim plugin is available here: https://github.com/pivotal/tmux-config. We’ve also integrated it into our vim-config configuration here: https://github.com/pivotal/vim-config.

Mouse Support

By default tmux has very little mouse support. We enabled significant mouse support within iTerm by customizing our .tmux.conf:

  • Selecting tmux panes
  • Resizing tmux panes
  • Scrolling

See this .tmux.conf template for more, but here’s the interesting section:

 # ~/.tmux.conf
 # Enable mouse support (works in iTerm)
 set-window-option -g mode-mouse on
 set-option -g mouse-select-pane on
 set-option -g mouse-resize-pane on
 set-option -g mouse-select-window on

Note that iTerm supports this configuration. We cannot vouch for Mac’s Terminal application’s level of mouse support.

OS-Level Copy-Paste

Highlighting with the mouse triggers tmux’s text selection, which is not OS X’s highlighting, and thus ⌘+c will not copy the highlighted text. Though we never fully solved this issue there is a workaround: hold down the ⌥ key (ALT/Option) while highlighting to trigger OS X’s selection — ⌘+c will now copy the text.

tmux selection — OS X will not copy this

Holding ⌥ — OS X will copy this!

Unfortunately this technique does not respect tmux’s panes and will select across the entire screen, but it’s better than nothing.

MacVim vs. Terminal Vim Keybindings

Why did MacVim and Vim have different keybindings if both use the ~/.vimrc file? The answer is the ⌘ key. To ease the transition from RubyMine and TextMate to MacVim we mapped many common ⌘-based keybinding which were unavailable in terminal-based Vim. My personal advice is to stay away from the ⌘ key if your team uses both MacVim and terminal Vim, but if that’s not possible at least make an extra <leader> KEY mapping for everything that uses ⌘.

Take a look at our sophisticated ~/.vimrc setup, including the keybindings file, where ⌘ bindings are paired with non- ⌘ keybindings.

Learning tmux-Specific Commands

There’s no way around this one. Though mouse support means one can avoid the tmux-pane selection and scrolling commands I highly recommend learning tmux well if you are using it consistently.

In practice we only use a handful of tmux commands often:

  • CTL+b % – new vertical split
  • CTL+b " – new horizontal split
  • CTL+b o – switch to other pane. Repeat to cycle through.
  • CTL+b c – create new tmux tab/window
  • CTL+b n/p/l – switch to next, previous, or last tmux tab/windows
  • CTL+b [ – Enter scroll/copy mode

Here are a couple of fun ones:

  • CTL+b SPACE – change arrangement of panes. Repeat to cycle through various arrangements.
  • CTL+b w – list tmux tabs/windows
  • CTL+b , – rename tmux tab/window

Once your team gets the hang of it they might even prefer the multiple tmux-pane workflow to a multi-app, multi-tab setup.

It’s a Fast Paced World

With such a plethora of remote pairing software and configurations it’s impossible to keep up. We would love to hear about your own experiences remote pairing with tmux and how you might improve upon our own techniques and configurations. Please post comments and let us know what you think.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Yaneeka Huq

Standup 7/16/2012: STI + Polymorphism needs base class

Yaneeka Huq
Monday, July 16, 2012

Interesting Things

  • STI + Polymorphism needs base class
class Movie < ActiveRecord::Base
  has_one :player, :as => :content
end

class Player < ActiveRecord::Base
  belongs_to :content, :polymorphic => true
end

and then, later we refactor Movie to use STI with Product…

class Product < ActiveRecord::Base ... end
class Movie < Product ... end

> movie = Movie.first
> movie.player
  Player Load (1.1ms)  SELECT "players".* FROM "players" WHERE "players"."content_id" = 144 AND "players"."content_type" = 'Product' LIMIT 1
 => nil

because players.content_type == ‘Movie’ but polymorphism uses the base class, ‘Product’

Fix: Add a migration to change the content_type column

UPDATE players SET content_type=’Product’ WHERE content_type=’Movie’

  • 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)
  • bloggerdome (22)
  • mobile (22)
  • 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 agile Feed
  1. ←
  2. 1
  3. ...
  4. 7
  5. 8
  6. 9
  7. 10
  8. 11
  9. 12
  10. 13
  11. ...
  12. 78
  13. →
  • 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 >