boon

package module
v0.0.0-...-bdbd220 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2021 License: MIT Imports: 7 Imported by: 0

README

boon 🌟

allow your Lua code to live in the cloud(s)

test

Introduction

Boon is a modified Lua runtime which was built with some broad goals:

  • Allow Lua chunks to be executed as HTTP server (maybe even (micro)service-able)
  • Allow Lua chunks to communicate with other servers and databases
  • Allow the runtime to be extensible

It ships with a lot of out-of-the-box usable add-ons to communicate via HTTP (addons/generic/http_client), handle JSON data (addons/generic/json), to be run as HTTP server (addons/http/*) and talk to databases (addons/databases). Contributions are welcome!

It also ships with pre-loaded modules (boon_generic.lua, boon_http.lua) which create a more natural interface to the underlying functionality (See Caveats for more detail).

Usage

To get started immediately; Utilize the prepared Docker setup. And just run following commands.

# To create and access Docker container ...
$ make demo
# ... (In container) to run a local Lua script as entrypoint
#     (e.g. `examples/welcome.lua` when run in boon root)
$ boon -entrypoint=path/to/file.lua 
# ... now take a look at http://localhost:8080

For a more details on the exposed functions, check out the Lua API Docs.

Checkout Docker Hub for the official ready-to-use images.

Building

Boon uses aarzilli/golua. So when building (e.g. cmd/server/boon.go, cmd/cli/boon.go) keep in mind that boon uses CGO and requires -tags to build with specific Lua versions.

For a quick start you can run make docker-luajit, which creates two alpine-based images boon:test and boon:luajit. Both of them are alpine images and come with a default boon and boon_cli binary. (Do not use boon:test for production)

Benchmark

on MacBook Air M1 '20 – 8Gb RAM

compiled with -tags luajit, file used as HTTP handler did some JSON encoding and rendered some response

$ ./wrk -t1000 -c1000 -d30s http://127.0.0.1:8080/
Running 30s test @ http://127.0.0.1:8080/
  1000 threads and 1000 connections
  Thread Stats   Avg      Stdev     Max   +/- Stdev
    Latency    37.66ms   47.18ms 566.97ms   84.43%
    Req/Sec    49.90     55.59     1.44k    91.23%
  1422566 requests in 30.11s, 379.87MB read
  Socket errors: connect 0, read 150, write 0, timeout 0
Requests/sec:  47243.04
Transfer/sec:     12.62MB

Lua API

-- GENERAL
boon.log(lua_string) -- write to log (in log format)

-- GENERIC
boon.json.decode(json_string) -- returns JSON value Lua table
boon.json.encode(lua_table) -- returns JSON string of Lua table
boon.http.methods.patch -- 'PATCH'
boon.http.methods.post -- 'POST'
boon.http.methods.get -- 'GET'
boon.http.methods.put -- 'PUT'
boon.http.methods.delete -- 'DELETE'

local request = {
  target=target_url,
  method=http_method,
  body=http_body_if_needed,
  headers={} -- table of headers e.g. ['content-type']='application/json'
}
boon.http.request(request)

ok, db = boon.postgres.connect(connection_string) -- connects to a postgres database (if not possible, ok == false and db == nil)
results = db.query(query_string) -- fetches results from database (returns lua table)
lastId, noRowsAffected = db.exec(query_string) -- executes a query on the database
ok = db.ping() -- pings the database

-- HTTP
boon.method -- HTTP request method
boon.scheme -- HTTP request scheme (http/https)
boon.host -- HTTP request host
boon.path -- HTTP request path
boon.query -- HTTP request query string
boon.response.set_header(name, value) -- sets response header (must be called before boon.response.status)
boon.response.status(code) -- sets the rsponse code e.g. 200
boon.response.write(content_string) -- writes to response
boon.redirect(target_url, code) -- redirects to target_url with status code
boon.request.set_header(name, value) -- sets request header (this is relevant when using redirect, since the CURRENT request object is used for the redirect)
value = boon.request.get_header(name) -- returns the value set for the header requested
paramTable = boon.request.query_parameters() -- returns all sent query parameters
formParams = boon.request.form_parameters() -- returns all sent post (and query) parameters; or nil and error
fileBytes, meta = boon.request.file(name) -- returns bytes of a uploaded file and meta info (e.g. content-type, ...); or nil and error 

Caveats

This package uses aarzilli/golua; which has some caveats on it's own. By default pcall and xpcall are both renamed with prefix unsafe_*. This is because Lua errors are incompatible with Go ones, so every extension created technically should not be called in a pcall or xpcall callback. If you do it might crash your software if some error arises on Go side. To handle this problem there are chunks pre-loaded (boon_generic.lua, boon_http.lua). The resulting module should be used to call ANY extension boon contains out-of-the-box (as the docs implicate). Any external extension should ship it's own module. The module should be used to do argument type checks or any other necessary steps, before arguments are passed into the Go context. By doing this, it is generally safe to use pcall and xpcall.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Handler

func Handler(b *Boon) func(http.ResponseWriter, *http.Request)

Returns a HTTP handler, ready to be plugged into any http.HandleFunc; uses NewState and registers in addition any HTTP add-on.

Types

type Boon

type Boon struct {
	// File executed
	Entrypoint    string
	GenericAddons []func(*lua.State)
	HttpAddons    []func(*lua.State, http.ResponseWriter, *http.Request)
	Logger        *log.Logger
	Output        io.Writer
	// Determines if Lua execution errors are logger or printed in the
	// respective mode(i.e. if a Lua error is output as HTTP response
	// (print statement) or if it is printed with the provided logger)
	LogErrors bool
}

Boon is a Lua runtime in Go

It was build with the goal in mind to extend Lua with some functions to be run as HTTP server and be able to handle JSON, external HTTP requests and databases.

Boon ships with a lot of out-of-the-box add-ons to do exactly that and more, and also allows you to extend it further by registering add-ons for the generic use (cli and http usage) and http only use.

func NewRuntime

func NewRuntime(entrypoint string) *Boon

Create a new runtime, which holds essential runtime information; Used as general starting point of using Boon.

func (*Boon) ExecuteFile

func (b *Boon) ExecuteFile()

Runs the entrypoint as-is. Uses NewState.

func (*Boon) NewState

func (b *Boon) NewState() *lua.State

Create a new state, with generic add-ons registered; To be used for simply creating a state based on the Boon runtime.

Immediately after calling NewState() add a line `defer state.Close()`, so safely handle the state on termination.

func (*Boon) RegisterGenericAddon

func (b *Boon) RegisterGenericAddon(f func(*lua.State))

Registers a generic add-on; applied for CLI and HTTP use

func (*Boon) RegisterHttpAddon

func (b *Boon) RegisterHttpAddon(f func(*lua.State, http.ResponseWriter, *http.Request))

Registers a HTTP add-on; applied ONLY for HTTP use

Directories

Path Synopsis
cmd
cli

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL