Gaia/Architecture Transition Proposal
- 1 Transition Proposal
- 2 Step 0: Mirror the architecture proposal into functional teams
- 3 Step 1: External Services
- 4 Step 2: Mirror functional teams into the codebase
- 5 Step 3: Scope logical blocks
- 6 Concurrent Steps
This is a proposal to migrate our current codebase to the new and unified architecture for Gaia apps mentioned in the Architecture Proposal.
This documentation tries to split the transition process into a multi-steps process. The documentation also try to see how parts of those steps can be done concurrently to avoid a pure linear process.
Note: Similarly to the architecture proposal, it is important to note that this proposal is not a detailed explanation of how to transition individual applications. The details belongs to individual app authors, which have the necessary knowledge of their applications.
Step 0: Mirror the architecture proposal into functional teams
The proposed architecture is about strict decoupling of the front-end and the back-end, and focusing on small pieces. This ultimately lead to fine grained parts, which can be classified into 3 high-level categories.
Those categories are:
Impact on functional teams
As of today, individuals are often working on those 3 categories at the same time. While some may focus more on one aspect over others, this model merge the responsibilities of all categories and distract individuals.
It also prevent categories to evolve independently and results into a general slow down.
In order to mitigate those issues it is proposed to create 2 new functional teams:
The functional teams will still exists, but will refocus on the back-end of a particular application.
This solution should also provide a better concerns isolation. For example, most of the time UX/UI concerns are unrelated to the back-end logic. Or many WebAPIs changes does not concerns the front-end logic.
The new structure can be visualize as multiple layers of concerns wrapping each others.
- One team for all front-ends, of all apps
- Likely a medium-consequent team
- Responsible of perceived performance
- High level of interaction with UX/UI
- One team per app back-end
- Likely a small teams
- Responsible of business logic
- High level of interaction with WebAPIs
- One team for all shared components
- Likely a mid-size team
- Responsible of developer story
- High level of interaction with Front-End and Back-end
Impact on User Story
All those teams can work concurrently, without having to worry about other teams.
It creates an asynchronous development model for User Story. Usually a user story will impact the front-end and the back-end team. Those teams can work on the user story asynchronously, and one team may have done its related part while the other may have not started yet.
But at some point, the front-end and the back-end needs to synchronized to validate the integration. Also both front-end and back-end may independently require to synchronize with the Toolkit.
The backlog of each team is scoped to the responsibility of one of the mentioned categories only. It should create more focused and smaller backlog for each teams, but require some additional synchronization.
As an example the front-end and the back-end should be sure to have a shared deadline for a defined feature. But front-end and back-end may have custom deadlines to work on this feature, as long the deadline if not targeting after the shared deadline.
Step 1: External Services
While applications will work offline, similarly to the current packaged model, applications may benefits from accessing remote servers.
Those remote servers will serve different purposes, such as distributing applications updates, synchronizing user datas and getting telemetry reports from real users.
Those servers should be set up by collaborating with different teams, like the Content Services team for example.
Applications are now hosted with an offline copy of the source code onto the device. A remote server will distribute small updates to the clients.
Each app may distribute an update when a change is ready and validated by QA, and it is not dependent of a specific Gecko version which is not available on the target.
In order to get real reports and application usage, a Telemetry server will be set up. Telemetry reports may contains various type of metrics, keyed by origin, such as the startup time for a specific view, the average number of contacts, or even a navigation map for a particular app.
Those datas may be used for decision making, assuming the correct set of reports is available to the relevant people.
User datas are now synchronized over a remote server. While it can be seen as a backup mechanism, it is mostly a mechanism to enable multiple UIs to access the same set of datas.
A client may then be a desktop application, or a mobile application.
Step 2: Mirror functional teams into the codebase
While the first step to enable this architecture is to reorganize teams, the same set of changes needs to be reflected into our codebase.
Note: There is no silver bullet to do it, there is only a big amount of work. That said, some rules are defined in order to help.
In order to enforce a strict separation between categories, it is suggested to explode Gaia into multiple repositories, such as:
- One repository per application back-end
- One repository per application front-end
- Multiple repositories for shared libraries/helpers/etc...
In order to ensure teams are working asynchronously and a team can not block an other one, it is also suggested to run tests on a per repository basis. If someone, break the tests of one repository, it should not prevent other teams to continue working.
- if a composing element is needed by more than one app, it should be the responsibility of toolkit
- Web Components
- if an helper is used by more than one app, it should be the responsibility of toolkit
- Service Worker Helpers
- Data Synchronization Helpers
- Telemetry Helpers
Front-End / Back-End divorce
This is nothing else than a long iterative process.
The end goal is to have those parts running in a pure independent fashion, with well defined scopes.
One likely scenario is that instead of reaching the ideal goal, the final results will look a bit funny.
In order to avoid that, a set of strict rules is defined for each parts.
- No business code / Only data-binding and user events handling
- No WebAPIs access
- Async UI
- All code runs inside a worker
- WebAPIs code can not run into workers (yet). It should be accessed via the bridge abstraction
- Business code
- No DOM access
Step 3: Scope logical blocks
TODO: Add a schema here
- Each view is independent from other views
- No cross-views communication
TODO: Add a schema here
- Stateless services
- One specialized service per panel