lua

package module
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jan 29, 2020 License: MIT Imports: 12 Imported by: 1

README

Concurrent LUA Executor

Go Report Card GoDoc

This repository contains a concurrent LUA executor that is designed to keep running a same (but updateable) set of scripts over a long period of time. The design of the library is quite opinionated, as it requires the main() function to be present in the script in order to run it. It also maintains a single VM per Script instance, protected by a mutex.

Under the hood, it uses gopher-lua library but abstracts it away, in order to be easily replaced in future if required.

Usage Example

Below is the usage example which runs the fibonacci LUA script with input 10.

// Load the script
s, err := FromString("test.lua", `
    function main(n)
        if n < 2 then return 1 end
        return main(n - 2) + main(n - 1)
    end
`)

// Run the main() function with 10 as argument
result, err := s.Run(context.Background(), 10)
println(result.String()) // Output: 89

The library also supports passing complex data types, thanks to gopher-luar. In the example below we create a Person struct and update its name in LUA as a side-effect of the script. It also returns the updated name back as a string.

// Load the script
s, err := FromString("test.lua", `
    function main(input)
        input.Name = "Updated"
        return input.Name
    end
`)

input := &Person{ Name: "Roman" }
out, err := s.Run(context.Background(), input)
println(out)         // Outputs: "Updated"
println(input.Name)  // Outputs: "Updated"

Modules

This library also supports and abstracts modules, which allows you to provide one or multiple native libraries which can be used by the script. These things are just ensembles of functions which are implemented in pure Go.

Such functions must comply to a specific interface - they should have their arguments as the library's values (e.g. Number, String or Bool) and the result can be either a value and error or just an error. Here's an example of such function:

func hash(s lua.String) (lua.Number, error) {
	h := fnv.New32a()
	h.Write([]byte(s))

	return lua.Number(h.Sum32()), nil
}

In order to use it, the functions should be registered into a Module which then is loaded when script is created.

// Create a test module which provides hash function
module := &Module{
    Name:    "test",
    Version: "1.0.0",
}
module.Register("hash", hash)

// Load the script
s, err := FromString("test.lua", `
    local api = require("test")

    function main(input)
        return api.hash(input)
    end
`, module) // <- attach the module

out, err := s.Run(context.Background(), "abcdef")
println(out) // Output: 4282878506

Benchmarks

Benchmark_Serial/fib-8         	 5870025	       203 ns/op	      16 B/op	       2 allocs/op
Benchmark_Serial/empty-8       	 8592448	       137 ns/op	       0 B/op	       0 allocs/op
Benchmark_Serial/update-8      	 1000000	      1069 ns/op	     224 B/op	      14 allocs/op

Documentation

Index

Constants

View Source
const (
	TypeNil = Type(iota)
	TypeBool
	TypeNumber
	TypeString
)

Various supported types

Variables

This section is empty.

Functions

This section is empty.

Types

type Bool

type Bool bool

Bool represents the boolean value

func (Bool) String

func (v Bool) String() string

String returns the string representation of the value

func (Bool) Type

func (v Bool) Type() Type

Type returns the type of the value

type Module

type Module struct {
	Name    string // The name of the module
	Version string // The module version string
	// contains filtered or unexported fields
}

Module represents a loadable module

func (*Module) Register

func (m *Module) Register(name string, function interface{}) error

Register registers a function into the module.

func (*Module) Unregister

func (m *Module) Unregister(name string)

Unregister unregisters a function from the module.

type Nil

type Nil struct{}

Nil represents the nil value

func (Nil) String

func (v Nil) String() string

String returns the string representation of the value

func (Nil) Type

func (v Nil) Type() Type

Type returns the type of the value

type Number

type Number float64

Number represents the numerical value

func (Number) String

func (v Number) String() string

String returns the string representation of the value

func (Number) Type

func (v Number) Type() Type

Type returns the type of the value

type Script

type Script struct {
	// contains filtered or unexported fields
}

Script represents a LUA script

func FromReader

func FromReader(name string, r io.Reader, modules ...*Module) (*Script, error)

FromReader reads a script fron an io.Reader

func FromString

func FromString(name, code string, modules ...*Module) (*Script, error)

FromString reads a script fron a string

func (*Script) Close

func (s *Script) Close() error

Close closes the script and cleanly disposes of its resources.

func (*Script) Name added in v0.0.2

func (s *Script) Name() string

Name returns the name of the script

func (*Script) Run

func (s *Script) Run(ctx context.Context, args ...interface{}) (Value, error)

Run runs the main function of the script with arguments.

func (*Script) Update

func (s *Script) Update(r io.Reader) error

Update updates the content of the script.

type String

type String string

String represents the string value

func (String) String

func (v String) String() string

String returns the string representation of the value

func (String) Type

func (v String) Type() Type

Type returns the type of the value

type Type

type Type byte

Type represents a type of the value

type Value

type Value interface {
	fmt.Stringer
	Type() Type
}

Value represents a returned

func ValueOf

func ValueOf(i interface{}) Value

ValueOf converts a value to a LUA-friendly one.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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