Live data from Hacker News

Move Fast and Fix Things

githubengineering.com

41–50 of 95 posts

Re: Move Fast and Fix Things

#41
TIL that github used to merge files differently than git because it used its own merge implementation based on git's code, to make it work on bare repos. Showcases a benefit of open formats and open source, showcases a downside as well (I'd never guess it might merge differently.)

It's a good thing nobody contributes to my github repos since noone had the chance to run into the issue...

Re: Move Fast and Fix Things

#42

I wish they would add the ability to fast-forward merge from pull requests. I know many large projects (including Django) accept pull requests but don't merge them on Github simply because of the mess it makes of the history.

In my team's projects, code review in PRs made a mess of the history (certain devs in particular :P). We switched to a squash merge based workflow to address it, git reflow is our particular poison: https://github.com/reenhanced/gitreflow

Re: Move Fast and Fix Things

#43
When running with Scientist enabled, doesn't that mean you will add both the runtime of the old/new implementation instead of just one implementation?

I could see this begin ok in most cases where speed is not a concern, but I wonder what we can do if we do care about speed?

Re: Move Fast and Fix Things

#44
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 as true as it can get. I'd like to reemphasis the bug-for-bug. Sometimes that's the only way you can drop-in replace a system.

Re: Move Fast and Fix Things

#45
post #36
post #28

Earlier quoted context omitted.

The word "debt" is not just a financial term. There are debts of gratitude, debts to society, debts of honour, and so there are also technical debts. Objecting to the name "technical debt" on the basis that it is not the correct financial use of the term is like objecting to the name "work day" on the basis that it isn't measured in joules. It's a category error.

[deleted]

Yet you have not given one example of a better term. If you're not part of the solution, you're part of the precipitate... here at the bottom of the page.

Re: Move Fast and Fix Things

#46

When running with Scientist enabled, doesn't that mean you will add both the runtime of the old/new implementation instead of just one implementation? I could see this begin ok in most cases where speed is not a concern, but I wonder what we can do if we do care about speed?

We could go look at the implementation/documentation of Scientist to confirm, but nothing says the comparison has to be happening on the response thread. You could fork a new thread to run the unused implementation without impacting response time, as long as you have the server capacity.

Re: Move Fast and Fix Things

#47

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.

The first thing to do is to try to minimize the scope of mutating operations: e.g, decompose a monolithic read-write operation into independent load, transform, and store. You can then easily test as much as possible (the load and the store) side-by-side. The parts that must have side effects are still hard, but at least there are fewer of them. (One variant of this would be to build your code such that you can always intercept side-effects, and then block the new code's side effects and compare with the old code)

The next thing is to try to take advantage of idempotence (and, by extension, try to make as many of your mutating operations idempotent as possible): there's nothing completely risk free, but you can at least verify idempotence for either ordering of new and old code, and if you're factored right, you can run both paths on the same input and verify they have the same side-effects and output.

Finally, making the observation that the new code must in general be backwards-compatible with the old code, and both versions need to be able to run concurrently (because this situation will always exist during deployment): in the worst case, you can always start with a limited deployment of the new path, which limits the amount of damage done if the new code is bad.

Re: Move Fast and Fix Things

#49

Earlier quoted context omitted.

> ...that is a high-risk approach that is usually without correspondingly high payoffs That's probably true, 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. Just because the risk will be realized in the long run doesn't mean it's not a risk.…

I think jerf was trying to say that when re-implementing something, re-implement it first then improve it, don't do both at once.

> re-implement it first then improve it

Right. I'm saying (poorly, I guess) that that doesn't always work. If the technical debt is sprinkled throughout your system or your organization is sunk deeply into a broken paradigm, you're in trouble. Sometimes you need to provide a completely new technology that serves many of the same use cases in a different way.

I'm not saying we should reach for rewriting things as our first instinct.

I am saying that your COM interface will need to be replaced some day. Or your COBOL business logic will become a liability. Or your frames-based web API will cost you business.

Incremental change leads you to a new local maximum, but sometimes that local maximum stunts your growth or even proves deadly.

Re: Move Fast and Fix Things

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

I think what works even better is to have "permission" to gradually change both the old and the new. It can drastically simplify the process of creating a replacement, if you're only replacing a slightly more sane version of the original instead of the actual original.
Post reply on HN