Software migration strategies

Software migration strategies

The architecture and code you write today is tomorrow's legacy. This talks discusses - besides some basics and theory - how you can safely apply big refactorings to your production environments with minimum risk. We will discuss examples of successful and failed migrations, and why this is not only a technical, but also a cultural issue.

9f40c41cec8ab0f4fd1e7900a69b1d3d?s=128

Soenke Ruempler

November 07, 2013
Tweet

Transcript

  1. Software Migration Strategies Symfony Live 2013 Berlin Sönke Ruempler

  2. “Chief Trolling Officer” at www.jimdo.com @s0enke github.com/s0enke ruempler.eu

  3. None
  4. “A [software] migration strategy must ensure that the system remains

    fully functional during the modernization effort.” http://en.wikipedia.org/wiki/Software_modernization
  5. None
  6. “If you break it, will you even notice?”

  7. “If noticed it, can you even fix it?”

  8. DONE Thanks!

  9. DONE

  10. Rewrite!!!1

  11. “It’s easier to write code than to read code.”

  12. Rewrite?

  13. “When you throw away code and start from scratch, you

    are throwing away all that knowledge. All those collected bug fixes. Years of programming work.” http://www.joelonsoftware.com/articles/fog0000000069.html
  14. Example!

  15. None
  16. None
  17. 3 years of downtime?

  18. && WASTE

  19. Positive example?

  20. https://engineering.groupon.com/2013/misc/i-tier-dismantling-the-monoliths/

  21. Ok, what was the difference?

  22. Partial rewrite.

  23. Long-living Feature Branches for Refactorings?

  24. None
  25. ==

  26. MERGE CONFLICTS!

  27. && WASTE

  28. Ok, how to do better?

  29. Branch by abstraction http://paulhammant.com/blog/branch_by_abstraction.html

  30. works with

  31. Clean Code

  32. Legacy Code

  33. One master/trunk

  34. Branch in the Codebase!

  35. ok, step by step lets start with legacy code, makes

    more fun ;)
  36. 1. Isolate the component which needs to be replaced to

    in order to fulfill a business requirement
  37. Migration Steps / Code examples that are: • production-ready, •

    no feature branch involved • can be deployed as-is • not introducing any downtime will be marked with a star.
  38. Possibility A: introduce and refactor to a new indirection layer

  39. Consumer Code Consumer Code Consumer Code Old component to be

    replaced
  40. Possibility 1: introduce and refactor to a new indirection layer

    Consumer Code Indirection Layer Old component to be replaced Consumer Code Consumer Code
  41. 2. Implement the new component Consumer Code Indirection Layer Old

    component to be replaced New component Consumer Code Consumer Code
  42. 3. Add a feature toggle / flip Consumer Code Indirection

    Layer Old component to be replaced New component Feature Flip Consumer Code Consumer Code
  43. 4. Remove old component and feature flip Consumer Code Indirection

    Layer New component Consumer Code Consumer Code
  44. 4a) Maybe remove the Indirection Layer as well? Consumer Code

    New component Consumer Code Consumer Code
  45. SUCCESS

  46. Ok, so I might not need the whole indirection layer

    in the end. So is it worth the effort?
  47. Possibility B: you may also use conditionals everywhere

  48. if the codebase is hard to refactor and the new

    indirection layer will get obsolete eventually anyway
  49. Consumer Code Consumer Code function doThis() { if (getconfig(‘migrate_legacy_component’) {

    // new implementation } else { // old implementation } } function doThat() { if (getconfig(‘migrate_legacy_component’) { // new implementation } else { // old implementation } } function doStuffs() { if (getconfig(‘migrate_legacy_component’) { // new implementation } else { // old implementation } } Consumer Code Feature toggles everwhere!
  50. Consumer Code Consumer Code function doThis() { // new implementation

    } function doThat() { // new implementation } function doStuffs() { // new implementation } Consumer Code
  51. Hint: Learn how to deal with spaghetti / legacy code

  52. None
  53. Ok what if I have to deal with data migrations?

  54. Consumer Code Indirection Layer Old component to be replaced New

    component Migration Decorator Consumer Code Consumer Code
  55. Decorator pattern! class MigrationStorageProviderDecorator implements StorageProviderInterface { public function __construct(

    StorageProviderInterface $oldStorageProvider, StorageProviderInterface $newStorageProvider ) { $this->oldStorageProvider = $oldStorageProvider; $this->newStorageProvider = $newStorageProvider; } }
  56. On-the-fly data migration class MigrationStorageProviderDecorator implements StorageProviderInterface { public function

    get($id) { if ($storageItem = $this->newStorageProvider->get($id)) { // found item in new storage, migration already done return $storageItem; } if ($storageItem = $this->oldStorageProvider->get($id)) { // found item in old provider, copy to new provider, then return $this->newStorageProvider->put($storageItem); return $storageItem; } throw new StorageItemNotFoundException(); } }
  57. Data migration worker

  58. BTW: This is Continuous Integration!

  59. Protip: Always separate code cleanups from functional changes in commits!

  60. Ok, so what’s up with the two initial rules?

  61. “If you break it, will you even notice?”

  62. MTBF vs. MTTR

  63. Verify Branch by Abstraction Consumer Code Indirection Layer Old component

    to be replaced New component Verify by comparing old and new component results Consumer Code Consumer Code http://java.dzone.com/articles/application-pattern-verify
  64. None
  65. Gemba Walks

  66. Metrics everywhere

  67. “When code runs in production, it doesn't have the protection

    of a clean environment like your tests do.” http://about.travis-ci.org/blog/2013-06-11-unit-testing-your-production-code/
  68. None
  69. None
  70. “If you noticed it, can you even fix it?

  71. None
  72. One - some - many

  73. “Defend against the impossible, because the impossible will happen.” --

    Defensive Programming http://c2.com/cgi/wiki?DefensiveProgramming
  74. Logs

  75. www.loggly.com

  76. www.logstash.org

  77. www.graylog2.org

  78. SUCCESS

  79. Culture Requiments analysis / QA Development Production/Rollout Cont. Deployment Gemba

    walks High level acceptance tests (e.g. cucumber) Regression tests Isolating the component / scope of the migration Branch by Abstration Verify BBA Feature Flips Metrics (Audit)Logs One-some-many rollout Feature flags Recap
  80. Thanks! Questions?