Live data from Hacker News

Move Fast and Fix Things

githubengineering.com

81–90 of 95 posts

Re: Move Fast and Fix Things

#81
post #39

Earlier quoted context omitted.

>but it's also true that over a long enough timescale (100 years, to trigger a reductio ad absurdum) there is a very high risk that not replacing or rewriting that code will sink your technology and possibly your organization. Could you elaborate on what basis you claim this as a truth?

It's largely conjecture, admittedly. But there are very few pieces of software that last 40 years. Most companies don't plan to be out of business in the next 40 years. And many tech companies have gone out of business in even the last ten years because they weren't agile enough to adapt quickly to new technological changes.

I don't think that argument holds. Usually it's true, that if something hasn't lasted a long time, it likely won't last a long time in the future. But we live at a quasi-special time, close to a boundary condition.

There exists no software that has existed for 100 years, because software was invented sometime in the past hundred years. You can reductio ad absurdum that argument by saying, the week after the first software was written, that no pieces of software have lasted more than a week, and therefore very few pieces of software will last more than a week.

So very few pieces of software have lasted 40 years, because very few pieces of software were written at least 40 years ago.

Re: Move Fast and Fix Things

#82

For operations that don't have any side effects, I can definitely see how you could use the Science library. I'm curious though if there are any strategies folks use for experiments that do have side effects like updating a database or modifying files on disk.

Point the control to the real database, and the experiment to an unused database. After each request through Scientist, the two databases should be identical.

Or, make the output be the SQL command used to mutate the database. If the two outputs are different, then you've found something that needs investigation.

Re: Move Fast and Fix Things

#83
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…

The biggest issue with new things is unknown unknowns.

Re: Move Fast and Fix Things

#84
post #70
post #38

Earlier quoted context omitted.

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.

Git has a bunch of tests [0]. I expect that not all of them are git-the-official-CLI-specific.

> 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.

eeeeeeeeeh. Sensible companies will figure out how to massage the broken data into the correct form, then go on using the correct software.

[0] https://github.com/git/git/tree/master/t

Re: Move Fast and Fix Things

#85
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.

Sounds like a perfectly reasonable deprecation strategy.

To go a bit further...

Document and mark the old endpoints for deletion on the next major release.

Mark the old API endpoints as deprecated in minor releases when the new implementation is completed and the old API endpoint is wrapped.

Isn't that the whole purpose of SemVer?

Re: Move Fast and Fix Things

#86
post #32

The strategy of proxying real usage to a second code path is incredibly effective. For months before the relaunch of theguardian.com, we ran traffic to the old site against the new stack to understand how it could be expected to perform in the real world. Later of course we moved real users, as incrementally as we possibly could. The hardest risk to mitigate is that users just won't like your new thing. But taking bu…

> The hardest risk to mitigate is that users just won't like your new thing.

Do they ever? Why change the part users are used to?

Re: Move Fast and Fix Things

#87
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…

To me, I would have called that an "O(n^2)" (or whatever the proper non-linear order is) issue. The issue isn't that the algorithm is O(n), but that it's not O(n) when it could be! The other interpretations by andrewaylett and daveguy seem to be more accurate (and also agrees with my own thinking). But I could also see it being used for "the asymptotic complexity was hiding a huge constant".

Have you heard your interpretation used in the wild?

Re: Move Fast and Fix Things

#88

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.

That is my dream. Right now, many Windows GUIs (SmartGit/SourceTree) use 'git.exe' to manage the actual Git repositories. If libgit2 is fully mature, I can imagine more GUIs/tools will be built to manage/analyze the git repositories.

> Right now, many Windows GUIs (SmartGit/SourceTree) use 'git.exe' to manage the actual Git repositories.

For what it's worth, all of the Git functionality in Visual Studio uses libgit2.

Re: Move Fast and Fix Things

#89
post #72

Earlier quoted context omitted.

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.

There's a simpler method than this that provides even more surety, used by e.g. LibreSSL: 1. Start writing your new implementation (or heavily refactoring your old implementation, whichever), but in parallel, for each legacy function you remove, write an equivalent "legacy wrapper" function that implements the old API (and ABI; you have to return the same structs and all) in terms of the new API. 2. As you develop th…

Interesting! It seems almost as if the order doesn't matter, so long as each step is incremental and maintains the invariants of the previous step.

Re: Move Fast and Fix Things

#90
post #32

The strategy of proxying real usage to a second code path is incredibly effective. For months before the relaunch of theguardian.com, we ran traffic to the old site against the new stack to understand how it could be expected to perform in the real world. Later of course we moved real users, as incrementally as we possibly could. The hardest risk to mitigate is that users just won't like your new thing. But taking bu…

Out of curiosity - when you've done this type of proxy test, what do you do about write operations? Do you proxy to a test DB, or do you have your code neatly factored to avoid writing on the test path (I guess most code I've worked on that needed a rewrite also wasn't neatly factored :) ).
Post reply on HN