Live data from Hacker News

Move Fast and Fix Things

githubengineering.com

61–70 of 95 posts

Re: Move Fast and Fix Things

#61
post #60

Earlier quoted context omitted.

It's interesting that git is the same. [EDIT:] ...in that all issues and PRs are emailed rather than entered into a web app.

I'm not familiar with the Git project's inner workings, but their website git-scm.com tells me they are hosted on GitHub, which has a public issue tracker: https://github.com/git/git-scm.com/issues GitHub, however, only allows issues to be reported via private mail. I'm not aware of a 'public' issue tracker for GitHub anywhere (even if a mailing list).

This is the web application for the git-scm.com site. It is meant to be the first place a person new to Git will land and download or learn about the Git SCM system.

This app is written in Ruby on Rails and deployed on Heroku.

Re: Move Fast and Fix Things

#63
post #23

I'll highlight something I've learned in both succeeding and failing at this metric: When rewriting something, you should generally strive for a drop-in replacement that does the same thing, in some cases, even matching bug-for-bug, or, as in the article, taking a very close look at the new vs. the old bugs. It's tempting to throw away the old thing and write a brand new bright shiny thing with a new API and a new da…

This is probably very context dependent, because I've learned the opposite. For example, I was rewriting/consolidating a corner of the local search logic for Google that was spread throughout multiple servers in the stack. Some of the implementation decisions were clearly made because of the convenience of doing so in a particular server. But when consolidating the code into a single server, the data structures and p…

I didn't read the parent comment as reproducing the exact same logic perfectly. More as a definition of the interface between the external code and the part to replace and matching that interface closely with the replacement.

This isn't always possible but seems like a reasonable objective given my experience.

Re: Move Fast and Fix Things

#64

How does Scientist work with code that produces side effects? In the example, presumably both the new and old each create a merge commit. Maybe these two merge commits are done in in-memory copies of the repo so that the test result can just be discarded, but what about in the general case where a function produces an output file or some other external effect?

I would think that the operation would either (a) have to be pure or (b) be executed in two different environments. I think going for (a) is the easier approach. If you produce an output file, make a pure operation that generates the contents, then write it as a subsequent operation. Now you can test the contents against each other, but only actually write one of them.

Basically, create an intermediary object that represents your state change and test those. Then "commit" the change from control and discard the one from the experiment.

Re: Move Fast and Fix Things

#65
post #15
post #3

I am trying to understand why the new merge method needed to be tested online via experiment. Both correctness and performance of the new merge method could have been tested offline working with snapshots (backups) of repos. Could a github engineer shed more light here?

Author here. 5 years ago I would have agreed with you and logged e.g. 10 million merge requests to replay them offline. But one thing I've found over the years (which may seem obvious in retrospect) is that staging environment are not identical to production. Particularly not when it comes to finding sneaky bugs and performance regressions -- the code doesn't run on the same exact environment it will run when it is d…

TL;DR: In theory, theory and practice are the same. In practice, they are not.

Re: Move Fast and Fix Things

#66

How does Scientist work with code that produces side effects? In the example, presumably both the new and old each create a merge commit. Maybe these two merge commits are done in in-memory copies of the repo so that the test result can just be discarded, but what about in the general case where a function produces an output file or some other external effect?

You'd only want to use pure functions in this manner. If external state is being modified, you can use a monad, or similar, to contain it.

Re: Move Fast and Fix Things

#67
post #23

I'll highlight something I've learned in both succeeding and failing at this metric: When rewriting something, you should generally strive for a drop-in replacement that does the same thing, in some cases, even matching bug-for-bug, or, as in the article, taking a very close look at the new vs. the old bugs. It's tempting to throw away the old thing and write a brand new bright shiny thing with a new API and a new da…

You can break this down even more.

As we speak, I'm "replacing" old code by just writing a wrapper around it with the new API it should have.

Then I'll rewrite it without the wrapper, bug-for-bug.

And then I'll actually fix the bugs.

Re: Move Fast and Fix Things

#68
post #62

Does anyone know what an "O(n) issue" is? I can think of a few possible meanings in the usage here, but I've never heard it before and they all seem wrong.

Using a linked-list where the actual access pattern is random and an hash table is more suitable would be the most obvious, especially since this is C code.

Similar things includes C-style string functions like strlen() and so on that require iterating over an unknown length array. Caching (or better avoiding!) this work can save a lot of computing time. Example from libgit2: https://github.com/libgit2/libgit2/commit/7132150ddf7a883c1f...

In fact C-style string is a rich source of O(n) performance issues. And git is full of strings like filenames.

Re: Move Fast and Fix Things

#69
post #62

Does anyone know what an "O(n) issue" is? I can think of a few possible meanings in the usage here, but I've never heard it before and they all seem wrong.

It's an issue where processing something took O(n) time, when an algorithm to process it asymptotically more quickly (say O(log n)) would be more appropriate.

The old code probably works properly for the average case, but will really blow up on pathological cases. My best personal example was an optimisation pass that turned out to be exponential in the worst case. On average `n` was small, so no-one cared, until a pathological case came up where compile time ballooned to over half-an-hour. Working out that the operation could be done in a linear way only shaved a fraction of a second off the average case, but brought the half-hour case down to a few seconds.

Re: Move Fast and Fix Things

#70
post #38

This is tangential, but given the increasing functionality and maturity of libgit2, I wonder if it would yet be feasible to replace the Git command-line program with a new one based on libgit2, and written to be as portable as libgit2. Then there would be just one Git implementation, across the command line, GUIs, and web-based services like GitHub. Also, the new CLI could run natively on Windows, without MSYS.

While I think the libgit2 initiative is fantastic, I don't think there needs to be just one Git implementation. One of my favourite things about git is that the underlying storage and protocol is really simple and straight-forward to implement. You could do a lot of it in shell scripts, if you wanted to. The stateless storage is simple and consistent, but the thing that does vary is the various operating algorithms:…

No matter how simple and straight-forward it is, someone is going to fuck it up. And they're going to do so in a way that isn't immediately detectable, but screws the rest of the company because now they have to support something using the screwed up implementation.
Post reply on HN