Beispiel #1
0
func (lua *LuaExt) exec(reqLogger log.Logger, app *LuaApp, appID, reqId, script string, w http.ResponseWriter, r *http.Request) int {
	// FIXME(tsileo) a debug mode, with a defer/recover
	// also parse the Lu error and show the bugging line!
	start := time.Now()
	httpClient := &http.Client{}
	// Initialize internal Lua module written in Go
	logger := loggerModule.New(reqLogger.New("ctx", "Lua"), start, reqId)
	response := responseModule.New()
	request := requestModule.New(r, reqId, lua.authFunc)
	blobstore := blobstoreModule.New(lua.blobStore)
	kvstore := kvstoreModule.New(lua.kvStore)
	bewit := bewitModule.New(reqLogger.New("ctx", "Lua bewit module"), r)
	template := templateModule.New()

	// Initialize Lua state
	L := luamod.NewState()
	defer L.Close()
	setCustomGlobals(L)
	L.PreloadModule("request", request.Loader)
	L.PreloadModule("response", response.Loader)
	L.PreloadModule("logger", logger.Loader)
	L.PreloadModule("blobstore", blobstore.Loader)
	L.PreloadModule("kvstore", kvstore.Loader)
	L.PreloadModule("bewit", bewit.Loader)
	L.PreloadModule("template", template.Loader)
	// TODO(tsileo) docstore module
	// TODO(tsileo) cookies module
	// TODO(tsileo) lru module
	// TODO(tsileo) cache module => to cache response
	// TODO(tsileo) load module from github directly?
	// TODO(tsileo) ETag support

	// 3rd party module
	luajson.Preload(L)
	L.PreloadModule("http", gluahttp.NewHttpModule(httpClient).Loader)

	// Set some global variables
	L.SetGlobal("reqID", luamod.LString(reqId))
	L.SetGlobal("appID", luamod.LString(appID))

	// Execute the code
	if err := L.DoString(script); err != nil {
		// FIXME better error, with debug mode?
		panic(err)
	}

	// Apply the Response object to the actual response
	response.WriteTo(w)
	// TODO save the logRecords in the AppStats and find a way to serve them over Server-Sent Events
	// keep them in memory with the ability to dump them in bulk as blob for later query
	// logRecords := logger.Records()
	for _, logRecord := range logger.Records() {
		app.logs = append(app.logs, logRecord)
	}

	reqLogger.Info("Script executed", "response", response, "duration", time.Since(start))
	return response.Status()
}
Beispiel #2
0
//luaMain creates a new lua state for each file in ./lua
//and hands them the globals they need to interact with lazlo
func luaMain(b *lazlo.Broker) {
	broker = b
	var luaDir *os.File
	luaDirName := "lua"
	if luaDirInfo, err := os.Stat(luaDirName); err == nil && luaDirInfo.IsDir() {
		luaDir, _ = os.Open(luaDirName)
	} else {
		lazlo.Logger.Error("Couldn't open the Lua Plugin dir: ", err)
	}
	luaFiles, _ := luaDir.Readdir(0)
	for _, f := range luaFiles {
		if f.IsDir() {
			continue
		}

		file := fmt.Sprintf("%s/%s", luaDirName, f.Name())

		//make a new script entry
		script := LuaScript{
			Robot: &Robot{
				ID: len(LuaScripts),
			},
			State: lua.NewState(),
		}
		defer script.State.Close()

		// register hear and respond inside this lua state
		script.State.SetGlobal("robot", luar.New(script.State, script.Robot))
		//script.State.SetGlobal("respond", luar.New(script.State, Respond))
		//script.State.SetGlobal("hear", luar.New(script.State, Hear))
		LuaScripts = append(LuaScripts, script)

		// the lua script will register callbacks to the Cases
		if err := script.State.DoFile(file); err != nil {
			panic(err)
		}
	}
	//block waiting on events from the broker
	for {
		index, value, _ := reflect.Select(Cases)
		handle(index, value.Interface())
	}
}