The 152nd reading group meeting continued the microservices discussion started in the 151st paper. We read the “Blueprint: A Toolchain for Highly-Reconfigurable Microservice Applications” SOSP’23 paper by Vaastav Anand, Deepak Garg, Antoine Kaufmann, and Jonathan Mace. The premise of the Blueprint is the separation of the app’s logic and most of the infrastructure/ops concerns.
This separation allows the developers to write applications more abstractly against the Blueprint framework that hides concrete implementations of networking, storage systems, retry logic, etc. For example, instead of directly implementing a gRPC style communication between two services, an abstract Blueprint app will use a more generic Blueprint API for calling other services/functions.
When it is time to compile the apps, the devs specify concrete implementations that satisfy these more generic Blueprint interfaces. Blueprint will then handle compiling the app with desired libraries replacing the generic interfaces. This dependency injection allows engineers using Blueprint to quickly change their applications to run with different concrete infrastructure components (i.e., caches, databases, logging/tracing, networking/communication protocols, etc.), topologies, and even some error handling (retry strategies, circuit breakers, etc.)
The paper demonstrates the utility of Blueprint for research and prototyping by replicating all four broad types of metastable failures. The paper then shows how engineers can try different mitigation strategies by replacing several concrete components/libraries and retry strategies without rewriting the application and making minimal changes to the spec describing the transition from abstract app to concrete implementation.
Discussion
1) Utility of Blueprint. The paper shows some incredible results for research prototyping by allowing engineers to try the same application with different underlying components/libraries. However, Blueprint’s utility may be more limited outside of research. Currently, the system must operate with the “lowest common denominator” of features across all libraries/components in the same category. So, for example, if we have an interface for a Key-Value cache, some concrete caches may allow ranged reads while others do not, forcing the Blueprint’s API in this category to be limited to something that all supported caches can do, like simple read and write operations.
2) Extending to Modeling and Formal Methods. Blueprint operates by developers writing an abstract version of the application and making the abstract version concrete at compile time with an additional “wiring spec.” This notion of going from more abstract to more concrete is similar to the problem formal methods folks try to solve — refinement of the model into the implementation, so that both stay in sync throughout the development lifecycle. It does not seem like the abstract spec of the Blueprint app is abstract enough for model checking, but maybe something can be done to facilitate this. It would be nice to model-check the app specification and then provide the wiring spec to compile it in the actual running applications.
3) Comparison with ServiceWeaver paper (#151). Our previous paper talked about writing applications as logical monoliths instead of microservices and using a “smart” runtime to deploy the processes/components of the app most efficiently. Blueprint does not have the runtime for this; instead, it provides the engineers a way to specify the deployment (i.e., collocation of services) and other ops aspects and iterate through numerous combinations relatively quickly.
Reading Group
Our reading group takes place over Zoom every Thursday at 1:00 pm EST. We have a slack group where we post papers, hold offline discussions, and most importantly manage Zoom invites to paper presentations. Please join the slack group to get involved!