gopher-lua は Go で書かれた Lua 処理系です。
net/http で書かれたサーバーの設定を Lua で記述し、それを動的に変更してみます。
基本的な使い方
lua で設定ファイルを記述する場合は gopher-lua の作者が作成した gluamapperを使用すると簡単にできます。
package main
import (
"fmt"
"github.com/yuin/gluamapper"
"github.com/yuin/gopher-lua"
)
type dbConfig struct {
URL string
Port int
}
type Config struct {
Name string
Age int
DB dbConfig
}
var configLua = `
config = {
name = "hoge",
age = "31",
db = {
url = "localhost",
port = "3306"
}
}
`
func main() {
L := lua.NewState()
if err := L.DoString(configLua); err != nil {
panic(err)
}
var config Config
if err := gluamapper.Map(L.GetGlobal("config").(*lua.LTable), &config); err != nil {
panic(err)
}
fmt.Printf("%s\n%d\n%#v", config.Name, config.Age, config.DB)
}
実行結果
$ go run example.go
hello
hoge
31
main.dbConfig{URL:"localhost", Port:3306}%
設定を動的に変更する
サーバーに設定ファイルを受け取るURLを作成して、設定ファイルの内容を変えてみます。
package main
import (
"fmt"
"io/ioutil"
"net/http"
"github.com/yuin/gopher-lua"
"github.com/yuin/gluamapper"
)
type dbConfig struct {
URL string
Port int
}
type Config struct {
Name string
Age int
DB dbConfig
}
var initialConfig = `
config = {
name = "hoge",
age = "31",
db = {
url = "localhost",
port = "3306"
}
}
`
var (
L = lua.NewState()
config = Config{}
)
func DumpLuaConfig(w http.ResponseWriter, r *http.Request) {
fmt.Fprintf(w, "Name=%s\nAge=%d\nDB=%#v\n", config.Name, config.Age, config.DB)
}
func UpdateLuaConfig(w http.ResponseWriter, r *http.Request) {
luaScript, err := ioutil.ReadAll(r.Body)
defer r.Body.Close()
if err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "%v", err)
return
}
if err := L.DoString(string(luaScript)); err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "%v", err)
return
}
if err := gluamapper.Map(L.GetGlobal("config").(*lua.LTable), &config); err != nil {
w.WriteHeader(http.StatusBadRequest)
fmt.Fprintf(w, "%v", err)
return
}
fmt.Fprint(w, "ok")
}
func main() {
if err := L.DoString(initialConfig); err != nil {
panic(err)
}
if err := gluamapper.Map(L.GetGlobal("config").(*lua.LTable), &config); err != nil {
panic(err)
}
http.HandleFunc("/config/dump", DumpLuaConfig)
http.HandleFunc("/config/update", UpdateLuaConfig)
http.ListenAndServe(":8080", nil)
}
実行結果
- 初期設定
$ curl localhost:8080/config/dump
Name=hoge
Age=31
DB=main.dbConfig{URL:"localhost", Port:3306}
- 設定を変更する
$ curl -X POST 'localhost:8080/config/update' -d 'config =
{
name = "test",
age = "123123",
db = {
url = "localhoooooost",
port = "12345"
}
}'
ok
- 設定を確認する
$ curl localhost:8080/config/dump
Name=test
Age=123123
DB=main.dbConfig{URL:"localhoooooost", Port:12345}
サーバーを再起動せず設定ファイルを変更できました。
その他
同様の手法を使えば、恐らく hcl や toml でも可能だと思います。