Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Uber's new mobile architecture

6.377 visualizaciones

Publicado el

This presentation runs you through why we decided to create a new architecture and how we managed to rewrite and launch Uber’s Rider app with this new architecture in record time. We’ll talk through the core principles of the new architecture and why we think it’s a perfect fit for creating reliable, highly maintainable mobile applications, especially when you’re working at scale and have a large mobile team.

Publicado en: Ingeniería
  • Penis Enlargement and Enhancement Techniques: What REALLY Works?!? ➤➤ https://tinyurl.com/yy3nfggr
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Stop getting scammed by online, programs that don't even work! ▲▲▲ https://tinyurl.com/y4urott2
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Like to know how to take easy surveys and get huge checks - then you need to visit us now! Having so many paid surveys available to you all the time let you live the kind of life you want. learn more...■■■ https://tinyurl.com/realmoneystreams2019
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • You can now be your own boss and get yourself a very generous daily income. START FREE...■■■ https://tinyurl.com/make2793amonth
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí
  • Hello! High Quality And Affordable Essays For You. Starting at $4.99 per page - Check our website! https://vk.cc/82gJD2
       Responder 
    ¿Estás seguro?    No
    Tu mensaje aparecerá aquí

Uber's new mobile architecture

  1. 1. Uber’s New Mobile Architecture Uber Mobility April 19th, 2017
  2. 2. Why a new architecture? Tuomas Artman
  3. 3. Uber’s entire mobile team 4 ½ years ago
  4. 4. “What if we changed everything?”
  5. 5. 99.99% availability of core flows Enable global roll-back of core flows to a guaranteed working state Testing as a first-class citizen Architectural goals
  6. 6. 99.99% availability of core flows Enable global roll-back of core flows to a guaranteed working state Testing as a first-class citizen Support Uber’s growth for years to come Narrow and decouple functionality as much as possible Architectural goals
  7. 7. 99.99% availability of core flows Enable global roll-back of core flows to a guaranteed working state Testing as a first-class citizen Support Uber’s growth for years to come Narrow and decouple functionality as much as possible Provide rails for both design and code Consistency in engineering, consistency in UX Architectural goals
  8. 8. 99.99% availability of core flows Enable global roll-back of core flows to a guaranteed working state Testing as a first-class citizen Support Uber’s growth for years to come Narrow and decouple functionality as much as possible Provide rails for both design and code Consistency in engineering, consistency in UX Monitoring is a first-class citizen Automatic analytics, logging, debugging, and tracing Architectural goals
  9. 9. 99.99% availability of core flows Enable global roll-back of core flows to a guaranteed working state Testing as a first-class citizen Support Uber’s growth for years to come Narrow and decouple functionality as much as possible Provide rails for both design and code Consistency in engineering, consistency in UX Monitoring is a first-class citizen Automatic analytics, logging, debugging, and tracing De-risk experimentation Application framework with Plugin API Architectural goals
  10. 10. 99.99% availability of core flows Enable global roll-back of core flows to a guaranteed working state Testing as a first-class citizen Support Uber’s growth for years to come Narrow and decouple functionality as much as possible Provide rails for both design and code Consistency in engineering, consistency in UX Monitoring is a first-class citizen Automatic analytics, logging, debugging, and tracing De-risk experimentation Application framework with Plugin API Make magic Performance second to none, graceful degradation on low-end devices and networks Architectural goals
  11. 11. Copyright Tsahi Levent-Levi Multiplatform architecture Double the effectiveness of teams
  12. 12. Timeline
  13. 13. RIB Architecture Application Framework Dependency management Reactive data flows Scoping Compartmentalization Analytics UI Components Mapping Testability Experimentation Plugins Threading model Storage Location services Logging Monitoring Networking Routing Code gen Business-logic driven Open source
  14. 14. Deep Scope Hierarchies Tony Cosentini
  15. 15. Dealing with State Lots of apps have tricky asynchronous, state issues At Uber, this compounds quite a bit Uber’s apps have a lot of asynchronous state, from multiple data sources 150+ contributors
  16. 16. Scopes? “The lifecycle in which an object exists.”
  17. 17. App Scope
  18. 18. RiderAppDelegate / RiderApplication { PickupRequestManager DestinationRefinementStream DriverLocationMapLayer … and a lot more stuff… }
  19. 19. What’s so bad about this?
  20. 20. Stability and Code Quality Impact Objects that live longer than necessary are exposed to more state they don’t need. In Uber’s apps in particular, many of these stateful objects observe different streams of data. This means these objects might get frequent updates even when they aren’t being used. class DriverIsOnTheirWayToaster { private boolean isOnTripAndHasNotBeenNotified; public DriverIsOnTheirWayToaster(TripStateStream tripStateStream) { tripStateStream.subscribe({ (state, driver?) -> if (state == ON_THEIR_WAY { isOnTripAndHasNotBeenNotified = true; showToast(driver!.name); } else if (state == OFF_TRIP) { isOnTripAndHasNotBeenNotified = false; } }) } }
  21. 21. Input and dependency contracts are diluted When objects live at app scope, they cannot have very rigid inputs and dependencies. Why does this class take an optional AuthToken if it’s really required? How does this hurt testing? public class AuthenticatedNetworkRequester { private AuthToken? authToken; public void makeRequest() { networkClient.makeRequest(authToken!) } }
  22. 22. Other Issues While most of the classes are very simple, having lots of objects around for the entire duration of the app’s lifecycle is not super efficient. Classes can grow to not have a clear purpose. Although it wasn’t as bad as some of the examples, there was no standard way to “scope” singletons and objects to different lifecycles of the app.
  23. 23. Previous Rider App Scope Hierarchy
  24. 24. How do we improve this?
  25. 25. Improvements Lots of our bugs are state related. A pattern or framework to encourage creating objects only when relevant would help here. The view hierarchy doesn’t really line up with business logic. We should create a hierarchy based on business logic states, which does not necessarily map to what is on the screen. There was no easy, consistent way to create your own scopes.
  26. 26. Scopes Based on business logic
  27. 27. Scopes Root doesn’t know anything - it can’t make any assumptions. Root
  28. 28. Scopes LoggedIn knows that you have valid non-null authentication credentials. Dependencies created and provided here can take non-null credentials without having to make any assumptions. Root LoggedIn
  29. 29. Moving AuthenticatedNetworkRequester to LoggedIn Scope public class AuthenticatedNetworkRequester { private AuthToken? authToken; public void makeRequest() { networkClient.makeRequest(authToken!) } }
  30. 30. Moving AuthenticatedNetworkRequester to LoggedIn Scope AuthToken is now guaranteed to be available. Other objects that depend on AuthenticatedNetworkRequester need to be in a logged in state to use it. If a dependency requires AuthenticatedNetworkRequester outside of the LoggedIn scope, it’s now a compile error. public class AuthenticatedNetworkRequester { private AuthToken authToken; public void makeRequest() { networkClient.makeRequest(authToken) } }
  31. 31. Scopes OnTrip knows that the user is logged in and on a trip. Dependencies created and provided here can take non-null credentials and all data related to a trip without having to make any assumptions. Root LoggedIn OnTrip
  32. 32. Moving DriverIsOnTheirWayToaster to OnTrip Scope class DriverIsOnTheirWayToaster { private boolean isOnTripAndHasNotBeenNotified; public DriverIsOnTheirWayToaster(TripStateStream tripStateStream) { tripStateStream.subscribe({ (state, driver?) -> if (state == ON_THEIR_WAY { isOnTripAndHasNotBeenNotified = true; showToast(driver!.name); } else if (state == OFF_TRIP) { isOnTripAndHasNotBeenNotified = false; } }) } }
  33. 33. Moving DrvierIsOnTheirWayToaster to OnTrip Scope Now DrvierIsOnTheirWayToaster is exposed to much less state - it’s easier to understand, and less prone to bugs. class DriverIsOnTheirWayToaster { public DriverIsOnTheirWayToaster(Driver driver) { showToast(driver.name); } }
  34. 34. Composable single-responsibility units Yi Wang RIB
  35. 35. Massive ViewController/Fragment
  36. 36. RIB Composable Single-responsibility Units
  37. 37. RIB Composable Single-responsibility Units
  38. 38. RIB Composable Single-responsibility Units
  39. 39. RIB Composable Single-responsibility Units
  40. 40. RIB Composable Single-responsibility Units
  41. 41. RIB Tree & Inter-RIB Communication Composing RIBs into features
  42. 42. RIB Tree & Inter-RIB Communication Composing RIBs into features
  43. 43. RIB Tree & Inter-RIB Communication Composing RIBs into features
  44. 44. RIB Tree & Inter-RIB Communication Composing RIBs into features
  45. 45. RIB Tree & Inter-RIB Communication Composing RIBs into features
  46. 46. View(Controller) Tree Composing RIBs into features
  47. 47. What about other architectures? MVC ● Massive ViewController ● Locked in view tree and business tree MVVM ● Massive ViewModel ● Locked in view tree and business tree VIPER ● Logic separation based on view ● Locked in view tree and business tree
  48. 48. What did RIBs give us? ● Rider app broken up into more than 500 RIBs ○ Many are reused with multiple parts of the tree ● All RIBs have less than 300 lines of code per class ● All business logic well unit-tested
  49. 49. Brian Attwell Plugins
  50. 50. ● Support Uber’s growth for years to come? ● Provide rails for both design and code ● De-risk experimentation Architectural goals Consider three of our architectural goals:
  51. 51. Support Uber’s growth for years to come RIBs give us code isolation We want more code isolation
  52. 52. Code Isolation Example
  53. 53. Code Isolation Example
  54. 54. Code Isolation Example
  55. 55. Code Isolation Example
  56. 56. Code Isolation Example
  57. 57. Support Uber’s growth for years to come Provide rails for both design and code? De-risk experimentation How do Plugins play into Architectural goals? Consider three of our architectural goals:
  58. 58. Home Screen
  59. 59. Interface: Router<? extends MapComponent> { } Example: NearbyVehiclesMapLayer PresentLocationMapLayer CurbsidePickupMapLayer DestinationRefinementMapLayer Home Screen
  60. 60. for (HomeMapLayerPlugin plugin: plugins) { attachChild(plugin.buildRib(component)); } Home Screen
  61. 61. Interface: ViewRouter<?> { } Example: SnapchatCardRouter RatingCardRouter TransitConnectionRouter EatsCardRouter PaymentsCardRouter
  62. 62. Interface: interface LocationRowProvider { Observable<SearchResult[]> query(input); } interface SearchResult { String tag(); Router buildRouter(parent); } Example: CalendarResultsPlugin SavedLocationsPlugin GeoSearchResultsPlugin FriendsLocationPlugin
  63. 63. Observable .combineLatest(plugins) .subscribe(BindLocationRowsConsumer)
  64. 64. @Override protected void didBecomeActive() { for (Work worker : mainScopedPluginManager.get()) { work.start(); } } Viewless plugins
  65. 65. Interface: interface MenuPlugin { MenuCategory menuCategory(); Router buildRouter(MenuPluginComponent) } enum MenuCategory { TOP, BOTTOM } Example: PaymentMenuPlugin FreeRidesPlugin HelpPlugin
  66. 66. Almost all features in the app can be written as code that plugs into the core of the app.
  67. 67. 80% of Rider’s Application Layer written as Plugins
  68. 68. New plugin points and changes to core get extra code reviewers added automatically.
  69. 69. Support Uber’s growth for years to come Provide rails for both design and code De-risk experimentation? How do Plugins play into Architectural goals? Consider three of our architectural goals:
  70. 70. Derisking Experimentation Roll out all new features as plugins Every plugin is initially A/B tested Every plugin can be disabled from our servers UI tests ensure the app is still functional when all plugins disabled
  71. 71. De-risking Experimentation
  72. 72. Engineers want to reuse existing plugin points and now know where the build new features We’ve prevented six outages in production by disabling plugins Statically ensured code isolation between the architecturally significant core of the app and the app’s features Results From using plugins
  73. 73. Development Velocity Able to sustain 500 diffs/week per platform Diffs landed per week doubled after finishing the four month rewrite Crash Free Rate Immediately after releasing the new app, crash rate was better than the old app iOS crash free free rate of 99.99% and climbing Android crash free rate of 99.9% and climbing Performance App starts 50% faster Developer Happiness 78.5 developer NPS score improvement Results From the new architecture
  74. 74. Thank you Proprietary and confidential © 2016 Uber Technologies, Inc. All rights reserved. No part of this document may be reproduced or utilized in any form or by any means, electronic or mechanical, including photocopying, recording, or by any information storage or retrieval systems, without permission in writing from Uber. This document is intended only for the use of the individual or entity to whom it is addressed and contains information that is privileged, confidential or otherwise exempt from disclosure under applicable law. All recipients of this document are notified that the information contained herein includes proprietary and confidential information of Uber, and recipient may not make use of, disseminate, or in any way disclose this document or any of the enclosed information to any person other than employees of addressee to the extent necessary for consultations with authorized personnel of Uber. eng.uber.com github.com/uber

×