From ee19890828f0aab44a0c6f073211c319b6745627 Mon Sep 17 00:00:00 2001 From: Jacob <2606873+unitoftime@users.noreply.github.com> Date: Wed, 30 Oct 2024 16:30:31 -0400 Subject: [PATCH] Add an example for hot reloading --- example/hot/main.go | 39 ++++++++++++++++++++++++++++++++++++ example/hot/plugin/plugin.go | 16 +++++++++++++++ example/hot/rebuild.sh | 30 +++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 example/hot/main.go create mode 100644 example/hot/plugin/plugin.go create mode 100644 example/hot/rebuild.sh diff --git a/example/hot/main.go b/example/hot/main.go new file mode 100644 index 0000000..9161462 --- /dev/null +++ b/example/hot/main.go @@ -0,0 +1,39 @@ +package main + +import ( + "time" + + "github.com/unitoftime/flow/example/hot/plugin" + "github.com/unitoftime/flow/hot" +) + +// Steps: +// 1. run rebuild.sh to build the initial plugin *.so file +// 2. Run main.go +// 3. Change something in the HelloWorld function in ./plugin/plugin.go +// 4. run rebuild.sh to rebuild the plugin *.so file. the main() function below will detect, reload the symbol and run it once + +// Note: You need to run rebuild.sh to build the plugin *.so file + +func main() { + // You can directly import the plugin package to use it immediately + plugin.HelloWorld() + + // This will search the provided directory for .so files and try to load them + p := hot.NewPlugin("./plugin/build/lib/") + + for { + time.Sleep(1 * time.Second) + if !p.Check() { continue } // When this becomes true, it means a new plugin is loaded + + // With our new plugin, we can lookup our symbol `HelloWorld` + sym, err := p.Lookup("HelloWorld") + if err != nil { + panic(err) + } + hello := sym.(func()) + + // Then we can call our Looked up symbol + hello() + } +} diff --git a/example/hot/plugin/plugin.go b/example/hot/plugin/plugin.go new file mode 100644 index 0000000..90dec32 --- /dev/null +++ b/example/hot/plugin/plugin.go @@ -0,0 +1,16 @@ +package plugin + +import ( + "fmt" +) + +// Note: Here you can change one function to the other while main.go is running. + +func HelloWorld() { + fmt.Println("Hello World") +} + + +// func HelloWorld() { +// fmt.Println("Goodbye Moon") +// } diff --git a/example/hot/rebuild.sh b/example/hot/rebuild.sh new file mode 100644 index 0000000..c488133 --- /dev/null +++ b/example/hot/rebuild.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +set -e + +PLUGIN_DIR=./plugin/ +BUILD_DIR=./plugin/build/ +BUILD_PKG_DIR=${BUILD_DIR}/pkg/ +BUILD_LIB_DIR=${BUILD_DIR}/lib/ + +mkdir -p ${BUILD_PKG_DIR} +mkdir -p ${BUILD_LIB_DIR} + +rm -f ${BUILD_LIB_DIR}/*.so + +VAR=$RANDOM + +# Note: I usually leave this uncommented, but I didnt want to accidentally wipe someones computer +#rm -rf ${BUILD_PKG_DIR}/* +mkdir -p ${BUILD_PKG_DIR}/tmp$VAR + +cp ${PLUGIN_DIR}/*.go ${BUILD_PKG_DIR}/tmp$VAR + +cd ${BUILD_PKG_DIR}/tmp$VAR +sed -i 's/package plugin/package main/g' *.go +cd - + +go build -gcflags=all=-d=checkptr=0 -buildmode=plugin -o ${BUILD_LIB_DIR}/tmp$VAR.so ${BUILD_PKG_DIR}/tmp$VAR + +echo "Finished Rebuild" $VAR +tree