Welcome to Yammer Engineering

We're on a mission to create enterprise software that people actually want to use. We are a social media startup backed by exceptional leadership and a validated revenue-generating business model. At Yammer, we value engineering excellence and product clarity above all else.

yammer.com
jobs.yammer.com

Yammer is hiring!
Flickr
Thursday
Jan192012

Testing Across Browsers with JavaScript and Webdriver

Although jQuery has done a lot to minimise cross browser DOM inconsistencies, sometimes you run into an area where there is still little browser consensus, and you have to experiment with each one.

Until recently, I dreaded this scenario; booting up a VM with an antiquated operating system to run a browser from last decade, made the days when I ran into browser problems stressful and long. And at Yammer we like to push browsers to the limit in pursuit of a great product, so these days were all too common.

On a recent project, which touched both content-editable elements, and manipulation of selections and ranges (both areas where most browsers disagree), I decided there had to be a better way, and came up with a test mechanism which took almost all the pain out of writing cross-browser code.

While none of the concepts are that unique, it's an easy technique that I plan to use more often.

I was prototyping a rich-text editor using content-editable divs. Those of you who have dived into this area are familiar with the completely different way browsers handle content-editable. In a bizarre turn of events, Internet Explorer actually has one of the more sane implementations.

I decided that, due to the inconsistencies, I was going to code test-first; that is, first write failing unit tests, and then fix them in each browser.

I was writing javascript, thus ideally I wanted my tests to also be in javascript — the less context switching the better when writing unit tests.

The most reliable system for cross browser testing at the moment is the Selenium project. I had very little interest in generating Selenium tests, but luckily the Selenium server speaks a simple language called the Web Driver protocol. Based around an earlier Google project for scripting browser interaction, Web Driver allows you to control a browser and run arbitrary javascript, using a simple set of commands.

Even better, there is a NodeJS module called wd that already implements this protocol in javascript. The pieces were all there and all I had to do was glue them together.

And there was remarkably little glue required. I didn't even have to set up a Selenium server- Yammer already has a Sauce Labs account for running other unit-tests, and this meant that I could simply plug in our creds and spawn whatever VM's and browsers I desired in the Sauce cloud.

I wrote a very simple test runner to run the tests synchronously, and a set of simple unit tests. With a single command in the terminal, they were running concurrently in each browser.

By testing very basic assumptions, locating the point where DOM implementations diverged was super easy. And with what seemed like very little effort, I was able to get a complicated and DOM heavy piece of code written and reliable.

To show you how simple it is to get the tests running, I thought it'd be cool to get you to run them now. SauceLabs have let me set up a public account so that you can run them on their test infrastructure. (They'll probably shut the account down in a few days, so if you're reading this later, you may have to open your own account).

All that you need to do is to clone my repo:

git clone git@github.com:yammer/Editable-Content.git

and then run:

node test/run.js --username yammer-demo --apikey 145c4ffa-8d74-4fd5-8905-25dcbf546e97 --browser firefox,iexplore@7,iexplore@8,googlechrome

The tests are now running. Each dot is a test completing successfully, and if your terminal supports colors, each color represents a browser. I've left a couple of failing tests in there so you can see the tracebacks. When running the tests on saucelabs, you get a link to a video of the tests being run so you can go back and watch the tests fail.

I'm excited that testing is becoming this easy. I hope that some of you reading, will take this and make it even better. And if you're interested in writing and testing great web apps, you should come interview with us here at Yammer. (Tell them Peter referred you ☺)

Tuesday
Jan102012

Yammer Drinkup - Javascript

We Yammer engineers take our JavaScript seriously.  And we love to drink.  That’s why we’re teaming up with Beerjs.com for our next Drinkup at SOMA’s Bloudhound on Tuesday, 1/17. Grab yourself a mason jar full of beautiful drink, chit-chat with some of our finest JavaScript engineers, and play a competitive game of Big Buck Hunter or two.  All drinks on us.  What’s not to love about that? Come join us! Please register here.

*This event is for engineers only.

Thursday
Jan052012

Rails Camp Australia

We are proud to be a sponsor of the 10th Rails Camp Australia!  We are sponsoring the bus and coffee.  Be on the look out for some Yammer schwag! The camp is sold out but you can sign up for the waiting list here.  

Wednesday
Jan042012

Managing Node.js Dependencies and Deployments at Yammer

The node community has seen a lot of discussion recently about managing dependencies with npm. In particular, people are debating the merits of using npm for deploying production applications. Mikeal Rogers's post, about checking modules dependencies into version control, sparked much of the discussion. Everyone has opinions, and certainly everyone's deployment concerns are different. I thought it might help folks to give some info about Yammer's experience.

There are several problems you may need to solve when dealing with dependencies in a non-trivial node app; like having multiple versions of the same module installed, or what to do with native modules that need to build a binary component. I'd like to talk about some real problems we had that led us to having all of the modules for our apps checked into the project repo.

Npm is a great tool, and as a long time member of the node community, I know it's been an uphill battle to get it to mostly meet everyone's needs. But it's still just a tool and not appropriate for all jobs. We still use npm extensively during development, but we found it less appropriate in a deployment plan. More specifically, we found that depending on the public npm repository server was problematic. If npm is for managing dependencies, it seems that by the time you're ready to deploy, most of these concerns should be over. Things should be pretty set in stone. So why depend on a remote npm server and a fluid deployment? Here's how we ended up at that conclusion.

We started going down the "recommended" route with a package.json for our project that listed all deps. The top level deps were pegged to specific versions so we didn't have those updating out from under us. This works well. But the second level deps still used version ranges, and we had several instances where they were updated without it being very obvious. For instance, express has a dependency on connect. But connect can be anything from version 1.5 to version 2.0. That's a big potential gap. So when you do npm install one day, you may get 1.7.1, the next week you may get 1.7.5. There is even a possibility that this will happen between the time you cut your release and the time you actually deploy, because npm always goes and gets the latest from the server. We had to mitigate this issue.

The next concern is that we had modules in various states. Some were taken straight from npm. Some were forked and modified by us. Some were developed by us internally and we didn't want those on the npm repo at all. Our first attempt at having more control over this situation was maintaining our own internal npm repository. It would replicate with the public repo to stay up to date, and it could still have our internal modules on it. This seemed like a good idea, and it solved a few problems. We could now have our yammer specific modules in our repo and available for only our deployments. But this also caused some other headaches. Here's a brief rundown:

  • We had several instances where some second level modules changed with an npm install. It didn't always break the build, but it's not something you can take on faith. Not everyone has the same ideas about what constitutes a patch version release. So we're combing through the updates trying to determine if there are any breaking changes.
  • Also for the modules we forked, we had to figure out how to have our version alongside the original version. We could rename our fork, but then we'd have to change other modules that were using the original names so they would get our updated version. Now you've got more forks.
  • The replication between our repo and the public repo was really slow and often failed. This was a couchdb problem I think, but still not something we wanted to deal with. The replication is key, because every time you have to do a full update you're talking about 4+ GB.
  • There was also some confusion every time a new person wanted to set up the project. We had to get them set up to point to our internal repo and make sure they understood how to manage our odd set of dependencies rather than just using the tried and true npm workflow.
  • We found that deployments had a lot of activity, which is not necessarily good. npm had to pull down several packages and connecting to our npm repo was kind of slow (it was hosted on ec2). It started to feel silly to make dozens of network calls on every server for every deployment.
  • Finally, we had to configure our replication so it didn't replicate our internal modules back out to the public repo. This is simple enough if you know what you're doing, but still a source of unnecessary worry.

So after some discussion, we started checking in all modules, and all of these problems literally went away. Now when someone wanted to install the app, they just did a clone, npm rebuild (more on this in a sec), changed some settings and they were off and running. We were fully aware of any module updates because they showed up in git diffs. And deployments were much easier.

There are still some things to consider with this approach, like native modules; those partially written in C/C++ that need to be compiled. We do not check in build directories and binaries. This is a simple entry in our .gitignore file (which is also checked in).


    #.gitignore
    bin
    scripts
    node_modules/**/out
    node_modules/**/build

 Ideally, native modules wouldn't always need to be rebuilt if they didn't change. But in practice, it's easier to just rebuild them with every deploy. For most native modules we've come across, this only takes a few seconds and still takes less time then pulling everything from npm each time. The "npm rebuild" command is very handy for this, and perhaps not something everyone is aware of. Npm rebuild checks all dependencies and runs build scripts if they are specified in the module's package.json file. We run this command after the checkout as part of our automated deploy.

You also need to add a few steps to your development process. Most things you can manage as normal: npm install modules, update your package.json, etc. But now when you go to check in changes, you'll see any updates that happened in your node_modules folder. You'll be able to see clear diffs of what changed and decide if this is an upgrade you're ready for. And when you are ready, "git add" these modules and check them in. And as an added maintenance step, if you're maintaining a separate repo for any forked or internal modules, you may need to update those as well. This seems onerous at first, but we've found that only a few members of the team end up maintaining modules. For most devs, their workflow is unchanged.

I hope I've painted a clear picture of an alternate option for managing node dependencies. But if checking in dependencies is still a concern, and you don't want to rebuild native modules on every server in your cluster, a second option is to have a deployment server. This server matches the hardware of your production systems. It may even just use one of your backup machines if you have those. Your deployment process is still simplified; checkout the release, npm install, and then test it out. Then you can run routines that tar that whole thing up and deploy it to the rest of the cluster. A deployment server may help avoid other potential snafus caused by different configuration on local machines.

Node is still a young technology, so "best practices" is still a vague term that is forming as we speak. Yammer engineering is constantly looking to improve and refine our procedures, so our time is spent on innovation and not headaches. I hope some of the information here is helpful for those developing deployment plans for node applications. Of course if you like what you heard, you should work with us.

Tuesday
Dec132011

Yammer Engineering Unleashed for Another Hack Day!

You might have heard of "Hack Day" before and wondered what it's all is about. At Yammer, hack day is a two day celebration of our product-oriented engineering culture. Hackers are given the freedom to form their own cross-functional teams and take a day to work on whatever they want to work on! Some use the day to scratch their own itch, others to learn something new, improve a feature, or just make everyone laugh. Then, 34 hours later, they demonstrate their hack to the entire company while a panel of judges give them the American Idol treatment! But, what is it that makes this such a huge part of who we are at Yammer?

"The awards are arbitrary and corrupt. I think that's key." said Kris Gale, the VP of Engineering and hack day judge who is rumored to have laser eyes. "The point isn't to win an award; the point is to have the freedom to learn new skills working with unfamiliar code, to implement cool ideas, and to get recognition during the demo from other engineers."

Adam Pisoni, CTO and hack day judge, added, "The cultural piece is important. Yammer engineering doesn't take itself too seriously. We constantly assume there are a nearly infinite ways we can improve. We also have a culture of free thinking which is the essence of hack day. Yammer Engineering is also a meritocracy." 

"Kris is right, though. Hack day isn't about getting rewards above the recognition you get from your peers. If you do something awesome, you don't need a crappy horse head for everyone to know what you did was awesome." 

Winners of Crappy Horse Heads This Hack Day

This hack day was the best one ever. There were hilarious and fun hacks, practical and necessary hacks, and hacks that went completely wrong!

  • The "Top Hack Award" went to Matthew Eernisse, Dan Erickson, Jeff Erickson, Paul Bloch, Joel Klabo, and Xiang Li for their Node.js and Geddy Web framework based Mobile Yammer Client.
  • The "People's Choice Award" was given to Ailin Fang , Jeffery Erickson, Kevin Hunt, and Lyn Stumfall for their Group Video Conference hack.
  • The "Best Presenter Award" went to Jordi Bunster for whatever the hell he was talking about on hack day... we're not quite sure.
  • The first ever "Bill Gates Innovation Award" was awarded to Matt Duncan for Yammy, his MS Word "Clippy" clone for Yammer.
  • In a shocker, the "Kris Gale Give Yourself an Award Award" didn't go to Kris Gale, but was given to another judge, Matt Kauffman, for his Sticky Header hack.
  • The "MBA Award" went to Ben Kudria for his Jargonator hack.
  • The "Virality Award" went to Kazu Omatsu for his hack, "The InviteIncreaser 5000."
  • The "George Jefferson Moving On Up Award" was given to Neil McCarthy and Scott Balentine for their Demo Network Creator. Then the award was renamed the "Neil McCarthy & George Jefferson Moving On Up Award" because Neil has won it for the last two hack days.
  • The "Sales Enablement Award" was awarded to Derek Steer for his Sales Leaderboard hack.
  • The "Most-Least-Practical Award" went to Matt Knopp and Ryan Kennedy for their Mustache Iconoclasti hack.

Some Thoughts from the Winners

moustache.io won the

Ryan Kennedy and Matt Knopp won the "Most-Least-Practical Award" this year. Their new "image resizer thingy," code name: iconoclastie, "seemed more 9-5 than hack day." So, instead, they made, "moustache.io!" The hack basically takes a network's icons, resizes them on the fly and, while doing so, scans them for faces onto which it affixes cartoon mustaches! Happy Movember! 

Matt Knopp: "The motivation for 'iconoclastie' was to take avatars out of the Rails stack. It isn't the best place for streaming images and reprocessing them. Further by reconsidering how to handle avatars it becomes easier to expose avatars to clients in a way that the client can then ask for better versions of the avatars. E.g. our default is 48x48 but iphone4 and 4S want 96x96. Etc."

Ryan Kennedy: "Most of the 'iconoclastie' work only took an hour or two. Many more hours were spent trying to get OpenCV (a facial recognition library) working with Java. Eventually we punted, signed up for a face.com token and used their API. I actually discovered a bug in the HTTP response headers from their API, which they fixed before we even presented our hack."

Matt Duncan took home the first ever "Bill Gates Innovation Award" presented for "Yammy!" You guessed it. He made his very own MS Word Clippy clone, for Yammer! "I believe all software of the future will be built around helpful animated characters." I bet you do, Matt.

Ben Kudria won the "MBA Award" this hack day for his hack which he should have called, "JarGONE." He first thought of it "after seeing a screenshot from a customer of ours of a message from a manager containing all sorts of jargon and lingo. I imagined that the message must be pretty confusing for anyone who is new to the company, or not from that department, etc."

Ben's favorite thing about hack day? "The drinking. Also the thinking outside the box. Also mustaches. I also spent the hack day assisting others and cleaning up some loose ends that I hadn't had the opportunity to look at."

ONE LAST QUESTION: "What's the best thing about hack day?"

"Ad-hoc, self-assembling teams." - Matthew Eernisse, this hack day's winner of the Best Overall Hack Award

"The freedom to push the product in whatever way you want, and then to see where other people pushed it." - Peter Braden, Scotch

"The creativity, excitement, and inspiration!" - Anna Do, two time winner of the Best Overall Hack Award

"It's a good opportunity to act on project ideas that may otherwise stay on my 'to do' or 'to learn' list indefinitely." - Neil McCarthy, back-to-back winner of the George Jefferson "Movin' on Up" Award

"Cronyism." - Matt Kauffman, hack day judge