On January 13th (two weeks ago), Lodash v4.0 was released. After waiting a week (for others to shake out the bugs), I branched our repos, bumped the lodash dependency in them, and fixed compatibility issues. I tried lodash-migrate, but it wasn’t particularly useful. lodash-migrate
works by running all lodash functions twice (once with the old version and once with the new), then logging if the results are different. That means any code with side effects will trigger a false positive or just break. Instead, I read the v4.0 changelog and reviewed every incompatible call in our codebase. (This wasn’t as hard as it sounds. There were only a few dozen.) After reviewing, testing, and manually poking around after deploying to staging, I deployed the new release to prod. Success!
…or maybe not. Soon after deploying, I noticed increased load on our back-end servers. When I ssh’d in to diagnose the issue, I saw that our back-end was replicating data like crazy. This didn’t endanger any information, but it was incredibly wasteful. Digging deeper, I noticed that if a single buffer in a workspace had changed, the entire contents of the workspace were copied in the next replication pass. Clearly, the lodash upgrade was responsible for this behavior, but how? I went back to my editor and looked at the code responsible:
I could reproduce the issue on staging, so I enabled debug logging and data logging. I immediately saw that not only did rbuf
and local_buf
have the keys, they also had the same the data! What was going on?! The only thing that changed was lodash, so I opened a REPL and double-checked the behavior of _.isEqual()
:
WTF? I couldn’t believe it. I ran similar object comparisons a dozen times. I triple-checked the JS objects I was comparing. I had to be making a mistake. I thought, “This can’t be a problem with lodash. It’s so basic.” I double-checked the ECMA spec to make sure object keys aren’t ordered. (They’re not.) I installed lodash 3 and re-ran the offending line in a REPL:
At this point, I was pretty sure this was a bug in lodash. I went to lodash’s GitHub project and prepared a bug report. Out of habit, I searched for existing issues. The result? An issue that had been closed 10 days earlier. A fix had been committed, but a new release hadn’t been tagged. :(
To fix the issue in production, I applied the patch to lodash in each project’s node_modules
, then deployed again. Not ideal, but at least the bug didn’t affect Floobits anymore.
Despite my comment on the issue, a new release still hasn’t been tagged. In my opinion, this is a critical bug. Object comparison is simply broken in lodash 4.0.0. I’m not sure why there’s been such a delay. While the code has been committed, a bug isn’t truly fixed until it’s deployed.