Working effectively at scale

Working effectively at scale

Presented at BA:Swiftable in November, 2019.

675a0b0e911ee6c1c270a8d86a44e716?s=128

Francisco Díaz

November 29, 2019
Tweet

Transcript

  1. Working e!ectively at scale

  2. Francisco Díaz franciscodiaz.cl - @fco_diaz

  3. Startups 2011 - 2017

  4. Airbnb 2017 - today

  5. None
  6. None
  7. None
  8. None
  9. None
  10. None
  11. None
  12. None
  13. None
  14. organizations ... are constrained to produce designs which are copies

    of the communication structures of these organizations — Conway's law
  15. How do you divide your codebase?

  16. Architectural layer

  17. User Flow

  18. What about Airbnb?

  19. None
  20. 1 million lines of Swift

  21. ~80 commits to master on any given day to the

    repo (Android + iOS)
  22. Bigger buckets

  23. None
  24. A user should be able to wishlist a listing from

    the booking flow
  25. How do they relate with each other?

  26. None
  27. None
  28. None
  29. 50 min local clean builds

  30. ~30 min !

  31. Buck HTTP Cache https://github.com/airbnb/BuckSample

  32. None
  33. ~5 min !

  34. None
  35. None
  36. Dependency inversion

  37. ‣High-level modules should not depend on low- level modules. Both

    should depend on abstractions. ‣Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.
  38. None
  39. A user should be able to wishlist a listing from

    the booking flow
  40. None
  41. Easy! WishListDataSource + interface!

  42. None
  43. WishListDataSource is still visible

  44. None
  45. Socializing best practices

  46. !

  47. +60 iOS developers

  48. Automating best practices

  49. Groups Modules

  50. Groups Modules Module Types

  51. Module Types Feature + Interface Service + Interface

  52. Feature A screen or a flow in the app

  53. Service Manage shared state or resources

  54. None
  55. None
  56. How do we enforce these best practices?

  57. /services /service_interfaces /features /feature_interfaces

  58. def service_interface( name, deps): max_visibility = [ "//ios/feature_interfaces/...", "//ios/features/...", "//ios/service_interfaces/...",

    "//ios/services/...", ]
  59. service_interface( name = "Networking", deps = [ "//ios/service_interfaces/Logging", ], )

  60. feature( name = "Booking", deps = [ "//ios/service_interfaces/Networking", "//ios/service_interfaces/WishListService", ],

    )
  61. iOS Platform

  62. Module creation needs to be easy

  63. None
  64. None
  65. rake make:module

  66. > Provide the type of module you want to create:

    1: Non Platform 2: Feature 3: Feature Interface 4: Service 5: Service Interface 4 > New module name: Swiftable > Provide a high level description of this module: This is a module to present at Swiftable
  67. Buck Human readable dependencies https://github.com/airbnb/BuckSample

  68. feature( name = "Booking", deps = [ "//ios/service_interfaces/Networking", "//ios/service_interfaces/WishListService", "//ios/feature_interfaces/HelpCenter",

    ], )
  69. None
  70. Feature A screen or a flow in the app

  71. None
  72. None
  73. None
  74. Dev Apps

  75. ~1 min Dev Apps

  76. Big buckets Small playgrounds

  77. None
  78. How do we get there?

  79. ~100 modules One module type: /libraries

  80. libraries/AirbnbBooking libraries/AirbnbBusinessTravel libraries/AirbnbHelpCenter libraries/AirbnbListings libraries/AirbnbNetworking libraries/AirbnbWishLists ...

  81. Before iOS Platform /libraries

  82. On the iOS Platform /services /service_interfaces /features /feature_interfaces

  83. How to get everybody on the iOS Platform?

  84. Remove libraries/ and start over

  85. !

  86. Progressively migrate

  87. Let's migrate WishLists Data Source

  88. libraries/WishLists

  89. None
  90. None
  91. None
  92. What are the dependency rules for libraries/?

  93. None
  94. Inbound dependencies Outbound dependencies

  95. Inbound dependencies Outbound dependencies

  96. None
  97. The interface module has stricter rules

  98. Migrate all the call sites

  99. As the owner of WishLists We don't control these

  100. None
  101. Calculated tech debt

  102. Inbound dependencies Outbound dependencies

  103. None
  104. we know our usage of Networking

  105. We control our dependencies

  106. Allow inbound dependencies from libraries/ Don't allow outbound dependencies to

    libraries/
  107. libraries/ has access to the iOS Platform

  108. The iOS Platform doesn't have access to libraries/

  109. Code on the iOS Platform has good boundaries

  110. while we allow for easier migration

  111. def service_interface( name, visibility = []): max_visibility = [ "//ios/feature_interfaces/...",

    "//ios/features/...", "//ios/service_interfaces/...", "//ios/services/...", ] add_visibility_for_legacy_module_structure(max_visibility)
  112. def add_visibility_for_legacy_module_structure(visibility): visibility.extend([ "//ios/libraries/...", ])

  113. We started migrating from the bottom up

  114. Try it ourselves !rst

  115. Pilot with others teams

  116. Should I implement this?

  117. Most likely NO

  118. There's no silver bullet

  119. Adapt

  120. Summary 1. Figure out where you're struggling 2.Create and document

    best practices 3.Automate best practices where needed
  121. ¡Gracias! franciscodiaz.cl/talks