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
  • Tools
  • Contact
    • Press Room
    • Press Releases
    • In The News
    • Press Kit
  • All
  • Labs
  • Standup
  • Tracker

When pairing doesn’t transfer knowledge fast enough

Charles Hansen
Tuesday, June 11, 2013

Pairing is great for knowledge transfer.  With a reasonably sized 3 pair project, you can completely avoid code reviews, training sessions, tutorials, or any other means of teaching a developer how something works.  I had a good amount of time on a 6 pair project with a ~15 developer-year code base and felt a lot of pain with poor knowledge transfer during that time.  Pairing just wasn’t enough.  We experimented with a few additional ideas during that time and found four that I would certainly use again on any future large project.  The parking lot, a pairing whiteboard, frequent technical retros, and developer documentation.  If your project is big enough, you might want to give these a shot.

Parking Lot

This has been used on a number of other Pivotal projects, but worth reinforcing.  As you are working through the day, if you ever create something other developers should use in the future (a helper method, or useful mixin, or new jasmine matcher, etc), write it on a whiteboard.  This goes double if there is something old that developers should have been using but didn’t know about.  I’ve found I typically write one thing per day.  At the beginning of standup (or perhaps before standup, with only the devs), go over all of the items on the whiteboard.  The same info could be contained in the standup itself, but there is a lot more useful info transferred this way in practice.

Cost:  A few minutes a day, less than the cost of standup.  The ask ticket for the whiteboard.

Pairing Whiteboard

Also taken from other projects.  We found that if pair rotation is basically random, you have very little control over what you work on and therefore very little control over what parts of the code you know.  We have every person’s name on a post-it note and write down every story that is carried over from the day before on a whiteboard with the owner’s post-it next to the story.  This goes for stories that weren’t started the day before but clearly need to be started today.  You then assign pairs based on who needs to learn what.  You can also use the same mechanism to create power pairs if the situation calls for it, but that doesn’t help knowledge transfer.

Cost:  Same as the parking lot, plus some post it notes.

Technical Retros

I used to think technical retros were only when the whole code base is about to fall apart or you need make a major infrastructure decision and want the whole team involved.  Developers know how to solve technical problems and we don’t need meetings to do this. It turns out these retros are great for knowledge transfer.  We only did this for a month or so before our team size was reduced for other reasons, but I’d recommend having technical retros on big teams once a week until you feel they aren’t helping and then dial back.

I have observed three mechanisms for this knowledge transfer.  If someone has been working on a component they don’t understand, this will end up in the unhappy column and now everyone knows that component needs more explanation.  If someone knows a component and thinks it should be changed, everyone else gets to listen in when the two people who actually understand it discuss it.  Lastly, when people discuss changes to the infrastructure, it ends up including good explanation of how the current infrastructure works.

Cost:   An hour-long meeting every week with the whole team is a lot.  Only really worth it on large teams.

Developer Documentation

I’ve noticed we treat documentation at Pivotal the same way we treat code comments, lies waiting to happen.  What is the point of writing down how some API is going to work when you already have tests describing the behavior and the API is just going to change next month?  This may be true for low-level documentation, but we have drawn a lot of value from higher-level documentation, showing general code flow and including examples of how pieces fit together.  We originally wrote the documentation because we are open source and needed to help out some third party devs, but it turned invaluable as a teaching resource.  Our documentation is split into two parts, one with info on how the code works (here) and a second “DevOps Manual” with info on dealing with our development and testing setup.  The DevOps manual is in a private repo.

Documentation writing was prioritized in tracker.  There were many stories “Document X” that built things up over time.  The stories were usually the result of action items from retros (technical or process) whenever a knowledge silo is identified.  Many pages were written by a pair with one experienced person and one new person.  This has the benefit of teaching the new person and forcing the experienced person to write something a new person can understand.

None of this addressed the ‘lies waiting to happen’ problem of documentation.  This is why we go over it all with each new developer on the project.  After a new developer has had some time to get their bearings, we put a chore in tracker to go over documentation with them (only if you are pairing with them of course).  The other part of that chore is to fix anything that is wrong.  This way every developer gets a baseline starting point and the documentation stays up to date.

Independent of knowledge transfer, the DevOps manual is pure gold.  It pays for itself as soon as something like “The VM running my third party database for development ran out of hard drive space and corrupted the database” happens more than once.  Whenever you fix something like that, even if you think it can’t possibly happen again, write it down.  When you set up that VM in the first place, write that down too.

One last note on documentation, even if you don’t use actual documents, it helps a lot to document in the code itself.  Detailed commit messages, detailed descriptions in tests, even code comments themselves occasionally.

Cost:  We have probably spent at a pair week or two writing our docs.  Maybe not worth it on a small project, but not too painful.  The DevOps manual itself would still be valuable on most projects.

 

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Why we don’t use OOCSS (but we should)

Charles Hansen
Saturday, May 25, 2013

I recently had the opportunity to pair with Nicole Sullivan (of OOCSS fame) for a few days on my current project.  I learned as much as I could about css components in the three days available and then rebuilt the most painful part of our UI with components over the next week.  I learned two broad things from this experience.  First, css components are amazing.  I didn’t realize how much pain I had in css until I saw how much easier it was with components.  We should definitely use them.  Second, css components feel weird in the normal web development world.  There are good reasons we haven’t used them at Pivotal.  It just turns out the reasons for not using them aren’t good enough.

I may write another post on why OOCSS is so amazing, but I think the more interesting post are the reasons to resist OOCSS.  Hopefully someone just trying it out will be pre-warned about these pain points and will be able to make a smoother transition.

1.  HTML and CSS are just not as important as the server code or javascript for a web developer.  I spend most of my time in ruby or javascript and am always looking for ways to make coding those things more sustainable.  I don’t spend very much time in HTML or CSS, so there isn’t the same drive to improve them.  I need big wins in CSS coding to justify changing anything.  Luckily, OOCSS fits the bill.

2.  You can’t test css.  Agile development relies heavily on the ability to refactor, which relies heavily on test coverage.  Say you had a page with many buttons, but the client only tells you about a new one every week.  With each new button, you add some html and css, and then some javascript click handlers.  After enough buttons, you refactor the javascript to reflect your new understanding of the page.  You can do this safely with enough test coverage, but how do you refactor the html/css without breaking something?  A style guide goes a long way here, but it’s not the same as test coverage.  In my refactor, I just had to spend the time comparing the look of the refactored css with old versions.  Mildly painful, but still worth it.

3.  The design patterns of rails are simply different than OOCSS.  If I want a page with a list of users, I will make a users_controller.rb with an index method.  I will make a user_list.js file for client interaction (assuming it is complicated enough to need one).  I also want to make a user_list.css file. Unfortunately, almost anything I would put in the user_list.css file is bad for OOCSS.  I need a lists css file which doesn’t know anything about users.  In fact, none of my css files should know anything about users if I can avoid it.  This isn’t hard to do once you realize it is important, but it never occurred to me until Nicole pointed it out.

4.  Javasript class names are usually semantic.  OOCSS class names are not.  They should not depend on the content in them, and might have absolutely nothing to do with the underlying business logic  If I have a list of users in my page, I naturally want to make a ul with a class like “user_list”.  In OOCSS most of the list styling for a user list should come from some generic class like ‘list_vertical’.  You don’t want the ‘user_list’ class unless the javascript needs it.  This felt unnatural for a few days, but I eventually got used to it.

5.  There is a lot of extra HTML in the early stages of an OOCSS refactor.  I ended up creating extra uls and divs in the weirdest spots just to get things to layout correctly.  And then there are all the extra classes.  You aren’t supposed to re-use javascript selectors in css, so you need to write new selectors for that.  You also shouldn’t use parent classes in your selector, so html that used to look like

html:
<div class="error">  
    Something went wrong!
    <button>Try again</button>
</div>

css:
.error { background-color: red; }
.error button { color: white; }
now needs to look like

<div class="error"> 
    Something went wrong!
    <button class=button_error">Try again</button>
</div>

.error {background-color: red;}
.button_error {color: white;}

You still need the “error” class to style the error div so the “button_error” class is just thrown on top.  The whole situation is made worse by html that is full of copy-paste.  In my refactor, there was a particular button type that was created over 100 times in our html and I wanted to add an OOCSS class to it.  We pulled it into a partial to solve the problem, but too much of this and it starts to feel like we need to refactor our html templating before we can refactor OOCSS.  I’ve been assured that a full OOCSS refactor actually results in 20-50% less html depending on the project.  The ‘extra html’ phase is only when you have added the OOCSS html but haven’t added enough that you can remove your old html scaffolding.  Even during this phase, the extra html isn’t so bad because at least you have a lot less css.

6.  Components only work if you see patterns in layout that repeat themselves.  Many of the components I am now using weren’t obvious to me as patterns worth extracting.  I didn’t start seeing them in the site until I became familiar with the common OOCSS components.  You do actually have to put effort into this.  The other failure mode here is if your website just doesn’t have repeatable patterns due to inconsistent design.  Now you need to add convincing your client to streamline the design to your list of tasks.  On the plus side, making css components is a very good way to show your client the inconsistencies in the design and should result in a better site.

None of the difficulties listed above are deal-breakers, but they do add up to a lot of headwinds in moving to OOCSS.  Even with those headwinds, the transition has already been an easy win for my current project and I believe most sites would find the same thing.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Launching Focused Jasmine Specs From RubyMine

Charles Hansen
Wednesday, May 8, 2013

RubyMine is great for launching focused rspec tests, but is a little trickier for launching Jasmine specs, but we have had it working on my current project using a shell script and RubyMine external tools .  The script relies on using sed to parse the first line of your spec file, so this actually only runs the describe block at the top of your file.  The steps for our setup below.

  • Create a shell script somewhere in your project:
  • Go to RubyMine -> Preferences -> External Tools -> +
  • This should launch a new tool dialog.  Fill in name, descriptions, etc
  • For program, you should link the script you just created.
  • For parameters, you should use “$FilePath$”
  • Bind this external tool under keymaps (look for the name you just gave it).  We use command-option-control-f8
  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 11/29/12: Time.now, more like Time.at(2011)

Charles Hansen
Thursday, November 29, 2012

Helps

mock object nil when it shouldn’t be

(rdb:1) @registration

RSpec::Mocks::Mock:0x3fda7eabfd68 @name=”mocked registration”

(rdb:1) @registration.present?
false
(rdb:1) @registration.nil?
false

  • mock objects don’t always define nil? or present?

Interestings

David Chelimsky handing off rspec

David Chelmisky is stepping down as the RSpec lead after 6+ years. http://blog.davidchelimsky.net/2012/11/28/myron-marston-and-andy-lindeman-are-rspecs-new-project-leads/

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 11/28/12: Mohawk Day!

Charles Hansen
Wednesday, November 28, 2012

Helps

Request log output in controller specs

We are getting info level log out put when running our specs from the controller examples. I don’t know how they are getting turned on nor how to turn them off

  • Crickets

default host when using url helpers in regular classes

How do most projects handle the default host for url helpers when the helper is being included in presentation classes etc?

  • Pass your controller to your presenter and ask the controller for url helpers

making rspec2 custom example groups

any one know how to define custom example groups in rspec and associate them with specs in a given folder.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 11/26/12

Charles Hansen
Monday, November 26, 2012

Interestings

dotenv Gem

Have you tried this gem? It kind of rocks it. Works great with a Heroku development environment. It even has files for different Rails modes, e.g. .env.test

https://github.com/bkeepers/dotenv

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Hunting Memory Leaks in Backbone

Charles Hansen
Tuesday, October 23, 2012

Ever notice your backbone app slows down considerably after using it for a few minutes? Or maybe your event callbacks are called more than once each time the event fires? Or my favorite, Chrome runs out of memory if you have a few tabs open that have run your entire Jasmine suite? This means you have backbone leaks.

I just spent the last week hunting these down in a very large app. It turns out the problem is tractable with a few guidelines. None of this is ground-breaking, but I wanted to put it all in one place.

1) The object retaining tree in the Chrome heap profiler is amazing. Use it.

2) Restrict use of views in closures, or as contexts to callbacks in event bindings. This is explained in much more detail here. I’ve also personally found nothing but trouble with _.bind for similar reasons.

More specifically, never use model.bind or model.on in a view without keeping track of that binding and remembering to unbind it when you want to tear down the view. This is the motivation for coccyx

3) ParentViews with childViews need to keep track of their children. When you tear down the parent view, you also tear down the child views. Before implementing this step, the object retaining tree for my zombie views was shockingly large. Afterwards, it was a manageable ~4 retainers for the zombies.

Parents keeping track of their children seems simple enough, but it is easy to lose track of the little devils.

For example:

ParentView = Backbone.View.extend({
    render: {
        //render the rest of the view first

        this.collection.each(function(model){
            var childView = new ChildView({model: model});
            this.$("ul").append(childView.render().$el);
        });
    }
});

loses any reference to the child views, and they will almost certainly leak (assuming the child views bind events to their models that need to be cleaned up).

Using the principles names from coccyx, the same code needed to be rewritten as

ParentView = Backbone.View.extend({
    render: {
        //render the rest of the view first

        this.tearDownRegisteredSubviews();

        this.collection.each(function(model){
            var childView = new ChildView({model: model});
            this.$("ul").append(liView.render().$el);

            this.registerSubView(childView);

        });
    }
});

where tearDownRegisteredSubviews calls tearDown on any registered subviews. This way, the only child views still in memory are those initialized in the most recent call to render. Those remaining views should be torn down when the parent is torn down.

View.tearDown itself can be a bit sticky because you still have to worry about event bindings from global objects and other difficult-to-clean sources, but those solutions are more project-specific.

Hope that points you in the right direction.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 10/26/2011: Nothing

Charles Hansen
Wednesday, October 26, 2011

Nothing today

  • 0 Shares
  • Share on Facebook
  • Share on Twitter

Standup 10/24/2011: Women who code meetup

Charles Hansen
Monday, October 24, 2011

Interesting Things

There will be a Women Who Code meetup on Tuesday. Sarah Mei will be giving a lightning talk at it about a day in the life of an engineer. The organization is for both women who are currently coders and those just interested in coding.

  • 0 Shares
  • Share on Facebook
  • Share on Twitter
Charles Hansen

Charles Hansen
San Francisco

Subscribe to Charles's Feed

Author Topics

jasmine (1)
rubymine (1)
agile (5)
backbone (1)
javascript (1)
  • About
  • Case Studies
  • Team
  • Community
  • Careers
  • Tools
  • 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 >