There’s recently been talk about when to make something a service vs. making separate Django apps that plug into the LMS process at runtime. I thought there was specific guidance on this in the wiki somewhere, but I couldn’t find it. So I’m curious to get people’s thoughts.
Someone recently framed it as a neat thought experiment: If we were building course-discovery today, would it still be a separate service? Or would we prefer to make a separate set of apps that runs in-process in the LMS?
It was originally built as a separate service for a number of reasons:
-
Faster Deployment Cycles
At the time that course-discovery was created, the deployment cycle for the LMS was somewhere between one and two weeks. Missing the release window was extremely painful. In contrast, a new service that didn’t carry all of edx-platform’s deployment baggage with it could run through CI/CD and have new commits be in production in under an hour. -
Team Autonomy
Having a shared service meant that you always had to worry about being delayed by another team–someone causing a bug that forces a rollback, or another team asking for a short delay in the release so they could their one critical feature over the line and not have to wait until the following week. Having a separate service meant that your team was fully in control. -
Operational Independence
In theory, having separate services gives a certain amount of resiliency, since a failure of one component doesn’t take down everything else with it. In practice, this is a mixed bag because many synchronous API dependency calls do exist between the LMS and other services, meaning that failures cascade anyway. In addition, the added data access challenges means that some of these calls are much more expensive than they might otherwise be (e.g. n+1 queries via REST API instead of doing a SQL join). -
Force Separation of Logic
If you’re in the same process, it’s much easier to throw in a quick hack and import some internal piece you’re really not supposed to. The thought here was that physical boundaries forced developers to think about these interfaces in a more rigorous way. -
Different Access Restrictions
Data in different services can vary wildly in sensitivity. Course discovery data at the time as purely catalog related and contained no user-specific data (I’m not sure if this is still the case). That’s much less sensitive than student or financial data. As a separate service, there is less of a chance that course-discovery apps will somehow be vulnerable in a way that exposes student data. -
Dependency Control
If you’re going from v2 to v3 of some big dependency that everything uses, then every repo that uses said dependency and is deployed together must be upgraded at the same time (or at least made compatible with both versions). This is a facet of Team Autonomy.
(If there are more reasons, please let me know.)
The tradeoffs have shifted since then, especially in terms of deployment speed. Services also carry a higher long term maintenance burden and significantly higher operational complexity. On the other hand, separate repos deploying in the same process has its own set of issues that we’ve run into.
I’m curious where people’s thoughts are on this. Which way would you go with course-discovery, and why?