<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta />
    <article-meta>
      <title-group>
        <article-title>Stack Traces in Function as a Service Framework∗</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Ádám Révész</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Norbert Pataki</string-name>
          <email>patakino@elte.hu</email>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>ELTE Eötvös Loránd University, Budapest, Hungary Faculty of Informatics, 3in Research Group</institution>
          ,
          <addr-line>Martonvásár</addr-line>
          ,
          <country country="HU">Hungary</country>
        </aff>
      </contrib-group>
      <pub-date>
        <year>2020</year>
      </pub-date>
      <fpage>29</fpage>
      <lpage>31</lpage>
      <abstract>
        <p>Containerization has become an essential approach in modern software engineering. Docker is a widely-used solution for separate services (like database, backend, etc.) and run them as a standalone, isolated process instance on the same host kernel. Kubernetes is distributed approach over Docker, it supports multiple hosts for the deployment. Kubeless is a new approach that aims at the functionwise deployment, so every subprogram can be deployed, scaled, operated separately, thererfore a functional programming approach can be realized in a modern, highly distributed realm. In this paper, we present our framework that provides a programming framework over Kubeless. However, many programming development tools are not available in this realm. Stack trace is a well-known construct in programming languages to follow the function calls. We propose a mechanism to retrieve the stack trace for realizing program errors easily.</p>
      </abstract>
      <kwd-group>
        <kwd>cloud</kwd>
        <kwd>Kubeless</kwd>
        <kwd>serverless programming</kwd>
        <kwd>stack trace</kwd>
      </kwd-group>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>
        Containerization has become an emerging approach in modern software engineering
since it enables the shipping of the software products with all required
dependencies in a platform-independent way [
        <xref ref-type="bibr" rid="ref2">2</xref>
        ]. Containerization eliminates the
virtualization costs of not used OS services and the kernel itself per container. Moreover,
containerization supports isolation efectively since the containers are seem to be
separate operating systems but they use a shared kernel [
        <xref ref-type="bibr" rid="ref9">9</xref>
        ].
      </p>
      <p>The containers are lightweight and they enable the fast and simple
deployment and configurations. However, a rather new abstraction is called Function as
a Service (FaaS) and this approach eliminates further configuration and
deployment cost. This approach provides the deployment of standalone function without
launching any virtual machine or container.</p>
      <p>
        We have developed an approach to enable functional programming paradigm
over Kubeless. However, this realm does not support the traditional programming
development tools for convenient work, such as debuggers. Stack trace is a
wellknown solution for realizing and detecting runtime problems [
        <xref ref-type="bibr" rid="ref10">10</xref>
        ]. Reconstruction of
bugs and incorrect program usage highly based on stack traces, therefore convenient
programming workflow requires it.
      </p>
      <p>You can see a stack trace received by execution of Java program:
Exception in thread "main" java.lang.StackOverflowError
at java.io.PrintStream.write(PrintStream.java:480)
at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221)
at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291)
at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104)
at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185)
at java.io.PrintStream.write(PrintStream.java:527)
at java.io.PrintStream.print(PrintStream.java:669)
at java.io.PrintStream.println(PrintStream.java:806)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:4)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
at StackOverflowErrorExample.recursivePrint(StackOverflowErrorExample.java:9)
...</p>
      <p>This stack trace illustrates the spreading of a StackOverflowError exception.
The actual function call chain can be read with filenames and line numbers, so one
can determine where the exception appeared first.</p>
      <p>However, collecting the stack trace when functions are executed parallelly on
many hosts is a dificult task. Unfortunately, the missing stack traces slow down
the debugging process significantly.</p>
      <p>We argue for a solution in our framework that retrieves stack trace in case
of runtime because stack trace is also required when the executed functions are
running on diferent hosts.</p>
      <p>In this paper, we present the background of serverless programming in section
2. We introduce our Kubeless-based functional framework in section 3. We present
the implementation background of stack traces in section 4. Finally, this paper
concludes in section 5.</p>
    </sec>
    <sec id="sec-2">
      <title>2. Serverless Programming</title>
      <p>
        Function as a Service (FaaS) is a category of cloud computing services that provides
a platform allowing programmers to develop, maintain, operate, scale and manage
application functionalities without the complexity of building and maintaining the
infrastructure typically associated with developing and deploying an application.
Building an application following this model is one way of achieving a “serverless”
architecture [
        <xref ref-type="bibr" rid="ref5">5</xref>
        ].
      </p>
      <p>
        Many cloud providers support serverless programming, for instance, Microsoft
Azure Lambda, Google Cloud Functions, etc [
        <xref ref-type="bibr" rid="ref7">7</xref>
        ].
      </p>
      <p>
        Serverless programming is a rather new approach, however, there are real-world
applications, for instance, Coca-Cola, Santander Bank and Expedia take advantage
of this new paradigm [
        <xref ref-type="bibr" rid="ref4">4</xref>
        ].
      </p>
    </sec>
    <sec id="sec-3">
      <title>3. LambdaKube Architecture</title>
      <p>Kubernetes is the most popular container orchestration system, Kubeless is a FaaS
system over the Kubernetes. We have created a functional approach over Kubeless.
The fundamental infrastructural elements are introduced along with the building
blocks of composable Kubeless functions discussing challenges, decisions and
implementation.</p>
      <sec id="sec-3-1">
        <title>3.1. Kubernetes</title>
        <p>
          Kubernetes is a container orchestration system which manages Docker containers
over multiple Docker hosts [
          <xref ref-type="bibr" rid="ref8">8</xref>
          ]. This paper does not discuss Kubernetes in details,
mentions only the essentials, used by other layers in the LambdaKube architecture.
        </p>
        <p>As an orchestration system, it provides the following services:
• pods and deployments – containers with their meta properties (Docker image,
environment variables for example), resource references (e.g. volumes and
configmaps) and replication controlling properties
• services – name resolution and load balancing
• configmaps and secrets – storing and serving configurations and secrets
• volumes – provisioning claimable volumes through multiple diferent volume
providers (local volume, cloud provided volumes, and other custom volumes)
• ingress – API gateway definitions for publicly exposed services
• custom resource definitions – supporting user-defined resource templates
composed of Kubernetes-native resources</p>
      </sec>
      <sec id="sec-3-2">
        <title>3.2. Kubeless Platform</title>
        <p>Kubeless is a serverless function platform implementation. Kubeless is responsible
to deploy and run code snippets – functions on Kubernetes in containers.</p>
        <p>
          Provided services:
• code snippet store – by default Kubeless uses config maps for storing code
• runtime for running the code snippets – Docker images for initializing,
(optionally) compiling and running the code snippets wrapped into language
environment specific wrapper code(s) [
          <xref ref-type="bibr" rid="ref1">1</xref>
          ].
• function registration – creating Kubernetes service which ensures service
discovery, so other services and functions can call/trigger the function over
HTTP
• message triggers – integrates with optionally installed message queue provider
(like Kafka, or in our case Nats) and ensures a specified functions trigger on
every new message on a specified topic
• function controller – a controller managing function deployments, triggers
and scale, an orchestrator over function nodes
        </p>
      </sec>
      <sec id="sec-3-3">
        <title>3.3. LambdaKube Platform</title>
        <p>LambdaKube, the project aims for a functional programming language, a
compiler and a platform with runtime frameworks where the compile time generated
functions can be deployed. The high-level architecture can be seen on Figure 1.</p>
        <sec id="sec-3-3-1">
          <title>3.3.1. Communication</title>
          <p>Since the programming language is functional and the FAAS realm is a distributed
environment, the first requirement of the platform seems obvious: the composition.
For composition asynchronous communication seemed to be fit, because of the
convenient use of unidirectional data flow and the elimination of the complexity
timeout introduces in synchronous communication.</p>
          <p>For asynchronous communication between services the industry recommends
message queues, such as Kafka. Our choice of message queue providers is Nats.
Nats is a lightweight message queue implementation fit to development purposes
of the platform at this stage and provides similar guarantees on messages (like
ordering) like Kafka, so on later stages, when big throughput occurs, bigger scaling
required, Nats can be replaced with Kafka with minor changes on the platform (even
can be made interchangeable with messaging libraries and dependency injection).</p>
        </sec>
        <sec id="sec-3-3-2">
          <title>3.3.2. State management</title>
          <p>Obviously the programming language layer, as a functional programming language
does not handle state. Also the promise of this project and FAAS architecture is
the stateless function.</p>
          <p>The current goal of the platform is implementing a unidirectional data flow with
asynchronous communication and more importantly in an FAAS solution idle time,
and active waiting should be avoided due to time based pricing on most providers
and the fact of wasting computing resources.</p>
          <p>Having the map construction for a case of introducing distributed (parallel)
computations the main focus is on the function passed to map but when the
function has been evaluated with all elements of the original context, something (lets
call it packer service) should wrap it into the new context and send the result to
the next stage of the pipeline. The state handling, and active waiting should be
avoided, so a state is introduced in LambdaKube platform.</p>
          <p>As of now the state storage service is a Redis, in-memory key-value pair database
designed for clustered – distributed usage. With this solution the packer service
is triggered on every new result from the function passed to map, stores it (with
other meta variables) in Redis. If all results arrived, wraps them and sends the
result in the new context to the next stage, then stops.</p>
        </sec>
        <sec id="sec-3-3-3">
          <title>3.3.3. Configurations</title>
          <p>Configurations for both Redis and Nats with their corresponding connection strings
and secrets are handled by the platform, stored in Kubernetes configmap and secret
resources.</p>
        </sec>
      </sec>
      <sec id="sec-3-4">
        <title>3.4. LambdaKube Runtime</title>
        <p>LambdaKube now uses Python, generates Python codes as snippets so the current
runtime (planned to be interchangeable in the future) is an extended version of
Kubeless provided Python runtime.</p>
        <p>LambdaKube runtime layer contains three main elements:
• General dependencies for interacting with the platform services (Redis and</p>
        <p>Nats).
•</p>
        <p>Wrapper framework which handles the incoming request from Kubeless
controller on trigger, sets up connections to platform services, invokes the
function call provided by the mounted code snippet, pushes the result to the next
stage.
• a Docker container image packs all elements listed above,</p>
        <p>Other elements like init container image and tasks are not discussed in this
paper.</p>
        <p>On function deployment, the references for configmap and secret entries are
injected into the function instance environment.</p>
      </sec>
      <sec id="sec-3-5">
        <title>3.5. LambdaKube low level representation</title>
        <p>LambdaKube compilation generates Python codes for the actual functions to be
wrapped into the runtime on deployment.</p>
        <p>
          Each function node gets its code generate into a separate service-name.py file.
The function names, message topic names and their relations are generated into a
descriptor file (picked up by Helm on deployment time [
          <xref ref-type="bibr" rid="ref3">3</xref>
          ]).
        </p>
      </sec>
    </sec>
    <sec id="sec-4">
      <title>4. Stack Traces in LambdaKube</title>
      <sec id="sec-4-1">
        <title>4.1. Tracing options</title>
        <sec id="sec-4-1-1">
          <title>4.1.1. Message queue</title>
          <p>With the current LambdaKube platform, a message queue is given. It could seem
easy to let the temptation win, and give the developers access to the queues so all
the calls, parameters and results are visible for them but this solution has multiple
issues:
• Message queue is part of the LambdaKube platform. The developer
(except platform developer) should not be interested in platform messages, and
hopefully they do not have to debug the platform itself.
• One computation message can be on multiple topics. Querying multiple
topics for the same session ID, merging their content into a single time line
and representing (visualizing) it in an informative way is a complex task, not
comfortable for day-to-day use.
• Developer experience is a metric that a development tool should respect with
topmost priority. There are other tools made for exactly this purpose
developed and maintained by active developer communities.
• Using the message queue for tracing as well would lead to lock the
implementation to message queues, making the support of other composition
technologies harder.</p>
        </sec>
        <sec id="sec-4-1-2">
          <title>4.1.2. Kubernetes level Jaeger</title>
          <p>
            Jaeger is an open source tool supporting OpenTracing API with multiple
integration options from Apache Thrift API to REST API [
            <xref ref-type="bibr" rid="ref6">6</xref>
            ]. It has API for querying
and a developer friendly web UI for browsing and querying traces.
          </p>
          <p>Jaeger can be installed into a Kubernetes cluster with ease, tracing all network
calls of the cluster, internal and external as well.</p>
          <p>While Jaeger sounds promising, using the same API as the popular Zipkin
tracing tool, the maturity level is good. The problem is the Kubernetes level
tracing. Kubernetes is the bottom-most level of our architecture (over container
level). For a developer who wants to debug a LambdaKube calculation, Kubernetes
calls, Kubeless calls are too much noise – in fact, with every function composition,
Kubeless controller, the message broker is called.</p>
        </sec>
      </sec>
      <sec id="sec-4-2">
        <title>4.2. LambdaKube level Jaeger</title>
        <p>Jaeger seems to be a good tracing implementation. LambdaKube should integrate
it.</p>
      </sec>
      <sec id="sec-4-3">
        <title>4.3. Jaeger integration</title>
        <p>When integrating tracing into LambdaKube the following have to be kept in mind:
• The generated code should not contain tracing as a boilerplate in all function.
• Runtime framework can inject tracing before and after each function
invocation.</p>
        <p>With trace messages sending can be injected to the runtime framework, the
tracing service – Jaeger – should be placed into the LambdaKube platform layer.</p>
      </sec>
    </sec>
    <sec id="sec-5">
      <title>5. Conclusion</title>
      <p>The LambdaKube Project has well-defined architectural layers which proven to be
extensible with a dynamic development tool, stack tracing. In this paper, multiple
options for tracing integration has been evaluated keeping in mind the separation
of concerns, respecting boundaries between architectural layers. The decision has
been made between a solution based on already used technologies in LambdaKube
and a popular tool which is made for the purpose and fits better into the
architecture.</p>
      <p>The solution proposed and introduced in this paper supports tracing, the
readability of trace messages and generated code as well – by not generating redundant
noise into the target code.</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <surname>Balla</surname>
            ,
            <given-names>D.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Maliosz</surname>
            ,
            <given-names>M.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Simon</surname>
          </string-name>
          , Cs.,
          <string-name>
            <surname>Gehberger</surname>
            <given-names>D.</given-names>
          </string-name>
          ,
          <article-title>Tuning Runtimes in Open Source FaaS</article-title>
          .
          <source>In Proc. of the Internet of Vehicles. Technologies and Services Toward Smart Cities (IOV 2019), Lecture Notes in Computer Science</source>
          , Vol.
          <volume>11894</volume>
          , Springer
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <surname>Bernstein</surname>
            ,
            <given-names>D.</given-names>
          </string-name>
          ,
          <article-title>Containers and cloud: From LXC to Docker to Kubernetes, IEEE Cloud Computing</article-title>
          , Vol.
          <volume>1</volume>
          (
          <issue>3</issue>
          ) (
          <year>2014</year>
          ),
          <fpage>81</fpage>
          -
          <lpage>84</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <surname>Buchanan</surname>
            ,
            <given-names>S.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Rangama</surname>
            ,
            <given-names>J.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Bellavance</surname>
            ,
            <given-names>N.</given-names>
          </string-name>
          ,
          <article-title>Helm Charts for Azure Kubernetes Service, Introducing Azure Kubernetes Service</article-title>
          , Apress, Berkeley, CA, pp.
          <fpage>151</fpage>
          -
          <lpage>189</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <surname>Castro</surname>
            ,
            <given-names>P.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Ishakian</surname>
            ,
            <given-names>V.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Muthusamy</surname>
            ,
            <given-names>V.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Slominski</surname>
            ,
            <given-names>A.</given-names>
          </string-name>
          ,
          <source>The Rise of Serverless Programming</source>
          ,
          <source>Communications of the ACM</source>
          , Vol.
          <volume>62</volume>
          (
          <issue>12</issue>
          ) (
          <year>2019</year>
          ), pp.
          <fpage>44</fpage>
          -
          <lpage>54</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <surname>Castro</surname>
            ,
            <given-names>P.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Ishakian</surname>
            ,
            <given-names>V.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Slominski</surname>
            ,
            <given-names>A.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Serverless Programming</surname>
          </string-name>
          (
          <article-title>Function as a Service)</article-title>
          ,
          <source>in Proc. of the 2017 IEEE 37th International Conference on Distributed Computing Systems (ICDCS)</source>
          , pp.
          <fpage>2658</fpage>
          -
          <lpage>2659</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <surname>Engel</surname>
            ,
            <given-names>T.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Langermeier</surname>
            ,
            <given-names>M.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Bauer</surname>
            ,
            <given-names>B.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Hofmann</surname>
            ,
            <given-names>A.</given-names>
          </string-name>
          ,
          <article-title>Evaluation of Microservice Architectures: A Metric and Tool-Based Approach</article-title>
          ,
          <source>In Proc. of the Information Systems in the Big Data Era (CAiSE</source>
          <year>2018</year>
          ),
          <source>Lecture Notes in Business Information Processing</source>
          , Vol.
          <volume>317</volume>
          , pp.
          <fpage>74</fpage>
          -
          <lpage>89</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <surname>Kritikos</surname>
            ,
            <given-names>K.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Skrzypek</surname>
          </string-name>
          . P.,
          <article-title>A review of serverless frameworks</article-title>
          ,
          <source>in Proc. of 2018 IEEE/ACM International Conference on Utility and Cloud Computing Companion (UCC</source>
          <year>2018</year>
          ), ACM, pp.
          <fpage>161</fpage>
          -
          <lpage>168</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref8">
        <mixed-citation>
          [8]
          <string-name>
            <surname>Medel</surname>
            ,
            <given-names>V.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Rana</surname>
            ,
            <given-names>O.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Banares</surname>
            ,
            <given-names>J. Á.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Arronategui</surname>
            ,
            <given-names>U.</given-names>
          </string-name>
          ,
          <article-title>Modelling Performance and Resource Management in Kubernetes</article-title>
          ,
          <source>In Proc. of IEEE/ACM 9th International Conference on Utility and Cloud Computing (UCC</source>
          <year>2016</year>
          ), pp.
          <fpage>257</fpage>
          -
          <lpage>262</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref9">
        <mixed-citation>
          [9]
          <string-name>
            <surname>Révész</surname>
            ,
            <given-names>Á</given-names>
          </string-name>
          , Pataki,
          <string-name>
            <given-names>N.</given-names>
            ,
            <surname>Containerized</surname>
          </string-name>
          <string-name>
            <surname>A</surname>
          </string-name>
          /B Testing,
          <source>in Proc. of the Sixth Workshop on Software Quality Analysis</source>
          , Monitoring, Improvement, and
          <string-name>
            <surname>Applications</surname>
          </string-name>
          (SQAMIA
          <year>2017</year>
          ), pp.
          <volume>14</volume>
          (
          <issue>1</issue>
          )-
          <volume>14</volume>
          (
          <issue>8</issue>
          ).
        </mixed-citation>
      </ref>
      <ref id="ref10">
        <mixed-citation>
          [10]
          <string-name>
            <surname>Schröter</surname>
            ,
            <given-names>A.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Bettenburg</surname>
            <given-names>N.</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Premraj</surname>
            ,
            <given-names>R.</given-names>
          </string-name>
          ,
          <article-title>Do stack traces help developers ifx bugs?</article-title>
          ,
          <source>In Proc. of 7th IEEE Working Conference on Mining Software Repositories (MSR</source>
          <year>2010</year>
          ), pp.
          <fpage>118</fpage>
          -
          <lpage>121</lpage>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>