A robust, large-scale web service can be difficult to engineer. When demand spikes, it must configure new machines and manage load-balancing; when demand falls, it must shut down idle machines to reduce costs; and when a machine crashes, it must quickly work around the failure without losing data. In recent years, serverless computing, a new cloud computing abstraction, has emerged to help address these challenges. In serverless computing, programmers write serverless functions, and the cloud platform transparently manages the operating system, resource allocation, load-balancing, and fault tolerance. In 2014, Amazon Web Services introduced the first serverless platform, AWS Lambda, and similar abstractions are now available on all major clouds. Unfortunately, the serverless computing abstraction exposes several low-level operational details that make it hard for programmers to write and reason about their code. This paper sheds light on this problem by presenting @math , an operational semantics of the essence of serverless computing. Despite being a small core calculus (less than one column), @math models all the low-level details that serverless functions can observe. To show that @math is useful, we present three applications. First, to make it easier for programmers to reason about their code, we present a simplified semantics of serverless execution and precisely characterize when the simplified semantics and @math coincide. Second, we augment @math with a key-value store, which allows us to reason about stateful serverless functions. Third, since a handful of serverless platforms support serverless function composition, we show how to extend @math with a composition language. We have implemented this composition language and show that it outperforms prior work.
Many large applications are now built using collections of microservices, each of which is deployed in isolated containers and which interact with each other through the use of remote procedure calls (RPCs). The use of microservices improves scalability -- each component of an application can be scaled independently -- and deployability. However, such applications are inherently distributed and current tools do not provide mechanisms to reason about and ensure their global behavior. In this paper we argue that recent advances in formal methods and software packet processing pave the path towards building mechanisms that can ensure correctness for such systems, both when they are being built and at runtime. These techniques impose minimal runtime overheads and are amenable to production deployments. Modern service-oriented applications forgo semantically rich protocols and middleware when composing services. Instead, they embrace the loosely-coupled development and deployment of services that communicate via simple network protocols. Even though these applications do expose interfaces that are higher-order in spirit, the simplicity of the network protocols forces them to rely on brittle low-level encodings. To bridge the apparent semantic gap, programmers introduce ad-hoc and error-prone defensive code. Inspired by Design by Contract, we choose a different route to bridge this gap. We introduce Whip, a contract system for modern services. Whip (i) provides programmers with a higher-order contract language tailored to the needs of modern services; and (ii) monitors services at run time to detect services that do not live up to their advertised interfaces. Contract monitoring is local to a service. Services are treated as black boxes, allowing heterogeneous implementation languages without modification to services' code. Thus, Whip does not disturb the loosely coupled nature of modern services.