Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Working effectively at scale

Working effectively at scale

Presented at BA:Swiftable in November, 2019.

Francisco Díaz

November 29, 2019
Tweet

More Decks by Francisco Díaz

Other Decks in Programming

Transcript

  1. Working
    e!ectively
    at scale

    View full-size slide

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

    View full-size slide

  3. Startups
    2011 - 2017

    View full-size slide

  4. Airbnb
    2017 - today

    View full-size slide

  5. organizations ... are
    constrained to produce
    designs which are copies of
    the communication structures
    of these organizations
    — Conway's law

    View full-size slide

  6. How do you
    divide
    your codebase?

    View full-size slide

  7. Architectural layer

    View full-size slide

  8. What about
    Airbnb?

    View full-size slide

  9. 1 million lines
    of Swift

    View full-size slide

  10. ~80 commits
    to master on any given day to the repo (Android + iOS)

    View full-size slide

  11. Bigger
    buckets

    View full-size slide

  12. A user should be
    able to wishlist a
    listing from the
    booking flow

    View full-size slide

  13. How do they
    relate
    with each other?

    View full-size slide

  14. 50 min
    local clean builds

    View full-size slide

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

    View full-size slide

  16. Dependency
    inversion

    View full-size slide

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

    View full-size slide

  18. A user should be
    able to wishlist a
    listing from the
    booking flow

    View full-size slide

  19. Easy!
    WishListDataSource
    + interface!

    View full-size slide

  20. WishListDataSource
    is still visible

    View full-size slide

  21. Socializing
    best practices

    View full-size slide

  22. +60
    iOS developers

    View full-size slide

  23. Automating
    best practices

    View full-size slide

  24. Groups
    Modules

    View full-size slide

  25. Groups
    Modules
    Module Types

    View full-size slide

  26. Module Types
    Feature + Interface
    Service + Interface

    View full-size slide

  27. Feature
    A screen or a flow
    in the app

    View full-size slide

  28. Service
    Manage shared
    state or resources

    View full-size slide

  29. How do we
    enforce these
    best practices?

    View full-size slide

  30. /services
    /service_interfaces
    /features
    /feature_interfaces

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  34. iOS Platform

    View full-size slide

  35. Module creation
    needs to be easy

    View full-size slide

  36. rake
    make:module

    View full-size slide

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

    View full-size slide

  38. Buck
    Human readable dependencies
    https://github.com/airbnb/BuckSample

    View full-size slide

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

    View full-size slide

  40. Feature
    A screen or a flow
    in the app

    View full-size slide

  41. ~1 min
    Dev Apps

    View full-size slide

  42. Big buckets
    Small
    playgrounds

    View full-size slide

  43. How do we
    get there?

    View full-size slide

  44. ~100 modules
    One module type: /libraries

    View full-size slide

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

    View full-size slide

  46. Before iOS Platform
    /libraries

    View full-size slide

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

    View full-size slide

  48. How to get
    everybody
    on the iOS Platform?

    View full-size slide

  49. Remove libraries/
    and start over

    View full-size slide

  50. Progressively
    migrate

    View full-size slide

  51. Let's
    migrate
    WishLists Data Source

    View full-size slide

  52. libraries/WishLists

    View full-size slide

  53. What are the
    dependency rules
    for libraries/?

    View full-size slide

  54. Inbound dependencies
    Outbound dependencies

    View full-size slide

  55. Inbound dependencies
    Outbound dependencies

    View full-size slide

  56. The interface module has
    stricter rules

    View full-size slide

  57. Migrate all the call
    sites

    View full-size slide

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

    View full-size slide

  59. Calculated
    tech debt

    View full-size slide

  60. Inbound dependencies
    Outbound dependencies

    View full-size slide

  61. we know our usage
    of Networking

    View full-size slide

  62. We control our dependencies

    View full-size slide

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

    View full-size slide

  64. libraries/ has access to the
    iOS Platform

    View full-size slide

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

    View full-size slide

  66. Code on
    the iOS Platform
    has good
    boundaries

    View full-size slide

  67. while we allow for
    easier migration

    View full-size slide

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

    View full-size slide

  69. def add_visibility_for_legacy_module_structure(visibility):
    visibility.extend([
    "//ios/libraries/...",
    ])

    View full-size slide

  70. We started
    migrating
    from the bottom up

    View full-size slide

  71. Try it
    ourselves
    !rst

    View full-size slide

  72. Pilot
    with others teams

    View full-size slide

  73. Should I
    implement
    this?

    View full-size slide

  74. Most likely
    NO

    View full-size slide

  75. There's no
    silver bullet

    View full-size slide

  76. Summary
    1. Figure out where you're struggling
    2.Create and document best practices
    3.Automate best practices where needed

    View full-size slide

  77. ¡Gracias!
    franciscodiaz.cl/talks

    View full-size slide