tinyFaaS is a lightweight FaaS (Function-as-a-Service) platform for edge environment with a focus on performance in constrained environments.
To use tinyFaaS in the version used in our paper, use git checkout v0.1
.
If you use this software in a publication, please cite it as:
T. Pfandzelter and D. Bermbach, tinyFaaS: A Lightweight FaaS Platform for Edge Environments, Proceedings of the 2020 IEEE International Conference on Fog Computing (ICFC '20), Sydney, Australia, 2020, pp. 17-24, DOI: 10.1109/ICFC49376.2020.00011.
@inproceedings{pfandzelter_tinyfaas:_2020,
author = "Pfandzelter, Tobias and Bermbach, David",
title = "tinyFaaS: A Lightweight FaaS Platform for Edge Environments",
booktitle = "Proceedings of the 2020 IEEE International Conference on Fog Computing (ICFC '20)",
year = 2020,
publisher = "IEEE",
pages = "17--24",
doi = "10.1109/ICFC49376.2020.00011"
}
For a full list of publications, please see our website.
The code in this repository is licensed under the terms of the MIT license.
Disclaimer: Please note that this will use your computer's Docker instance to manage containers and will allow anyone in your network to start Docker containers with arbitrary code. If you don't know what this means you do not want to run this on your computer. Additionally, note that this software is provided as a research prototype and is not production-ready.
tinyFaaS comprises the management service, the reverse proxy, and a number of function handlers. In order to run tinyFaaS, the management service has to be deployed. It will then automatically start the reverse proxy. Once a function is deployed to tinyFaaS, function handlers are created automatically.
Before you get started, make sure you have the following dependencies installed:
- Go (>=v1.22) to compile management service and reverse proxy
- Docker (>=v24)
- Make
- a writable directory (tinyFaaS writes temporary files to a
./tmp
directory)
Note that tinyFaaS is intended for Linux hosts (x86_64
and arm64
).
Due to limitations of Docker Desktop for Mac, installing and running docker-mac-net-connect
is necessary to run tinyFaaS on macOS hosts.
Running tinyFaaS on Windows computers (native or through WSL) is probably possible but has not been tested and is thus not recommended.
Start tinyFaaS with:
make start
The reverse proxy will be started automatically. Please note that you cannot use tinyFaaS until the reverse proxy is running.
To manage functions on tinyFaaS, use the included scripts included in ./src/scripts
.
To upload a function, run upload.sh {FOLDER} {NAME} {ENV} {THREADS}
, where {FOLDER}
is the path to your function code, {NAME}
is the name for your function, {ENV}
is the environment you would like to use (python3
, nodejs
, or binary
), and {THREADS}
is a number specifying the number of function handlers for your function.
For example, you might call ./scripts/upload.sh "./test/fns/sieve-of-eratosthenes" "sieve" "nodejs" 1
to upload the sieve of Eratosthenes example function included in this repository.
This requires the zip
, base64
, and curl
utilities.
Alternatively, you can also upload functions from a zipped file available at some URL.
Use the included script as a starting point: uploadURL.sh {URL} {NAME} {ENV} {THREADS} {SUBFOLDER_PATH}
, where {URL}
is the URL to a zip that has your function code, {SUBFOLDER_PATH}
is the folder of the code within that zip (use /
if the code is in the top-level), {NAME}
is the name for your function, {ENV}
is the environment, and {THREADS}
is a number specifying the number of function handlers for your function.
For example, you might call uploadURL.sh "https://github.com/OpenFogStack/tinyFaas/archive/main.zip" "tinyFaaS-main/test/fns/sieve-of-eratosthenes" "sieve" "nodejs" 1
to upload the sieve of Eratosthenes example function included in this repository.
To get a list of existing functions, run list.sh
.
To delete a function, run delete.sh {NAME}
, where {NAME}
is the name of the function you want to remove.
Additionally, we provide scripts to read logs from your function and to wipe all functions from tinyFaaS.
This tinyFaaS prototype only supports functions written for NodeJS 20, Python 3.9, and binary functions.
A good place to get started with writing functions is the selection of test functions in ./test/fns
.
HTTP headers and GRPC Metadata are accessible in NodeJS and Python functions as key values. Check the "show-headers" test functions for more information.
Your function must be supplied as a Node module with the name fn
that exports a single function that takes the req
and res
parameters for request and response, respectively.
res
supports the send()
function that has one parameter, a string that is passed to the client as-is.
Your function must be supplied as a file named fn.py
that exposes a method fn
that is invoked for every function invocation.
This method must accept a string as an input (that can also be None
) and must provide a string as a return value.
You may also provide a requirements.txt
file from which dependencies will be installed alongside your function.
Any other data you provide will be available.
Your function must be provided as a fn.sh
shell script that is invoked for every function call.
This shell script may also call other binaries as needed.
Input data is provided from stdin
.
Output responses should be provided on stdout
.
tinyFaaS supports different application layer protocols at its reverse proxy. Different protocols are useful for different use-cases: CoAP for lightweight communication, e.g., for IoT devices; HTTP to support traditional web applications; GRPC for inter-process communication.
To call a tinyFaaS function using its CoAP endpoint, make a GET or POST request to coap://{HOST}:{PORT}/{NAME}
where {HOST}
is the address of the tinyFaaS host, {PORT}
is the port for the tinyFaaS CoAP endpoint (default is 5683
), and {NAME}
is the name of your function.
You may include data in any form you want, it will be passed to your function.
Unfortunately, curl
does not yet support CoAP, but a number of other tools are available.
To call a tinyFaaS function using its HTTP endpoint, make a GET or POST request to http://{HOST}:{PORT}/{NAME}
where {HOST}
is the address of the tinyFaaS host, {PORT}
is the port for the tinyFaaS HTTP endpoint (default is 80
), and {NAME}
is the name of your function.
You may include data in any form you want, it will be passed to your function.
TLS is not supported (but contributions are welcome).
To make an asynchronous request, pass the X-tinyFaaS-Async
header with any value.
An asynchronous request means the client will receive a 202
response code immediately and no function results will be sent back.
curl --header "X-tinyFaaS-Async: true" "http://localhost:8000/sieve"
To use the gRPC endpoint, compile the tinyfaas
protocol buffer (included in ./pkg/grpc/tinyfaas
) for your programming language and import it into your application.
We already provide compiled versions for Go and Python in that directory.
Specify the tinyFaaS host and port (default is 9000
) for the GRPC endpoint and use the Request
function with the functionIdentifier
being your function's name and the data
field including data in any form you want.
When you stop the management service with SIGINT
(Ctrl+C
), the reverse proxy and all function handlers should be stopped.
You can also use:
make clean
OR
docker rm -f $$(docker ps -a -q --filter label=tinyFaaS)
docker network rm $$(docker network ls -q --filter label=tinyFaaS)
docker rmi $$(docker image ls -q --filter label=tinyFaaS)
rm -rf ./tmp
By default, tinyFaaS will use the following ports:
Port | Protocol | Description |
---|---|---|
8080 | TCP | Management Service |
5683 | UDP | CoAP Endpoint |
8000 | TCP | HTTP Endpoint |
9000 | TCP | GRPC Endpoint |
To change the port of the management service, change the port binding in the docker run
command.
To change or deactivate the endpoints of tinyFaaS, you can use the COAP_PORT
, HTTP_PORT
, and GRPC_PORT
environment variables, which must be passed to the management service Docker container.
Specify -1
to deactivate a specific endpoint.
For example, to use 6000
as the port for the CoAP and deactivate GRPC, run the management service with this command:
docker run --env COAP_PORT=6000 --env GRPC_PORT=-1 -v /var/run/docker.sock:/var/run/docker.sock -p 8080:8080 --name tinyfaas-mgmt -d tinyfaas-mgmt tinyfaas-mgmt
The tests in ./test
test the end-to-end functionality of tinyFaaS and are expected to complete successfully.
We use these tests during development to ensure no patches break any functionality.
The tests can also serve as documentation on the expected behavior of tinyFaaS.
Running the tests requires:
- Python >3.10 with the
venv
module - a tinyFaaS binary built for your host
Create a virtual environment for Python and install the necessary dependencies for CoAP and gRPC:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install -r test/requirements.txt
If you do not install these requirements, test runs are limited to invocations with HTTP.
Run the tests with:
$ make test
.............
----------------------------------------------------------------------
Ran 13 tests in 28.063s
OK
Tests will output a .
(dot) for successful tests and E
or F
for failed tests.
tinyFaaS output will be written to tf_test.out
.
On macOS, docker-mac-net-connect
is necessary to run tinyFaaS.
There is a known issue in docker-mac-net-connect
that silently breaks the tunnel when Docker Desktop enters its resource saver mode.
If you find that tinyFaaS does not start properly on your macOS host, try restarting the tunnel:
sudo brew services restart docker-mac-net-connect