In this project, I implemented a simple server-less application for executing Golang functions. Ghoster is a FaaS(Function as a Service) application. As the name suggests, it executes Golang functions on demand. Ghoster is a minimal version of server-less applications like AWS lambda. My purpose in creating this application is to take a deep dive into server-less systems. At this moment, Ghoster can handle simple Golang projects. It cannot handle complex applications like web/HTTP servers, etc.
The way it works is like a layered system. It contains an HTTP server in order to handle user requests, a metrics server to export Ghoster Prometheus metrics, a file server for managing functions/projects, and an exec component for handling FaaS requests.
In order to execute Ghoster, you need to set some environment variables, mount the functions directory (it will be used by file server and exec component in order to do the FaaS logic), and build the application docker image.
As you can see in the below table, in order to configure a Ghoster, you have to set the following environmental variables.
Name | Description | Type | Example value |
---|---|---|---|
HTTP_PORT |
Ghoster gateway port | integer | 8080 |
FILE_SERVER_PORT |
File server port | integer | 8081 |
METRICS_PORT |
Metrics exporter port | integer | 8082 |
METRICS_NS |
Metrics namespace | string | default |
METRICS_SS |
Metrics subsystem | string | ghoster |
POOL_SIZE |
Number of Ghoster concurrent workers | integer | 10 |
GC_INTERVAL |
Garbage collector interval in seconds | integer | 120 |
Ghoster stores Golang projects in a directory called functions
. The file server write new functions in this directory, and the exec component loads each function from this directory. Therefore, make sure to mount this directory.
Each project needs to have a main.go
, go.mod
, and README.md
. The readme file will be the description of each function. A suggested project structure is like this:
|_ internal/
|_ pkg/
|_ main.go
|_ go.mod
|_ go.sum
|_ README.md
When you want to upload a new function, make sure to use file server and upload your project as a .zip
format.
In order to build and run Ghoster using docker, you can use the two following commands:
docker pull ghcr.io/amirhnajafiz/ghoster:latest
docker run -d -it -e HTTP_PORT=8080 -p 8080:8080 -v $(pwd)/functions:/var/ghoster/functions ghcr.io/amirhnajafiz/ghoster:latest
Ghoster uses HTTP requests for registring projects, listing projects, and executing them. In this section we are going to give you some examples in curl
in order to work with Ghoster.
curl -i -X POST \
-F "file_name=subtraction" \
-F "file=@Archive.zip" \
localhost:8001/files
curl -i -X GET localhost:8080/functions
curl -i -X GET localhost:8080/functions/{function-name}
curl -i -X POST -H 'Content-type: application/json' -d '{"args": ["10", "2"]}' localhost:8080/functions/{function-name}
Input params are in JSON
format. The args
field is an array of input arguments to the function.
Ghoster Prometheus metrics are exported in an exporter. You can get them from localhost:8002/metrics
.
As mentioned before, Ghoster cannot handle complex functions like HTTP servers. Therefore, it might be good to work on exec component in order to handle complex application. Ghoster resource management is dependent on Go-routines. As they cannot handle some cases, it is a good idea to handle functions used resources.