Open johnny-morrice opened 8 years ago
Plugins ought not just to run once, but to persist for multiple renderings. This allows:
Have looked at all the Go plugin alternatives. They are all based on net/rpc.
This makes me sad because I don't want to use an RPC format. It has been really great so far to be able to dump process input, inspect it, use it as a config file, whatever. That's just not something I'd be able to do with RPC.
It seems using RPC based plugins really appeals to people who don't want to use pipes. For example, their app runs in a datacenter. I am targeting desktops, perhaps single servers.
For this reason, I think I will roll an ultra-minimal plugin interface based on JSON and process pipes. I am surprised something like this doesn't already exist in Go!
Hoping to get an implementation in less than 200SLOC!
README.md of planned package is below
Functional plugins with JSON and process pipes.
RPC is silly.
Go to bed.
// Plugin author defines her plugin
me := pjays.Plugin{
InType: "",
OutType: 0,
Input: os.Stdin,
Output: os.Stdout,
}
// Plugin spawns its goroutines
me.Go()
// Plugin author performs plugin logic
s := <- me.Rch
me.Wch <- len(string(s))
// Application author defines plugin reference.
plugin := pjays.PluginHandle{
Bin: "plugin-count",
InType: "",
OutType: 0,
Input: pipeIn,
Output: pipeOut,
}
// Spawn goroutines
plugin.Go()
// Plugin author communicates with plugin
plugin.Wch <- "hello"
cnt := <- plugin.Rch
fmt.Println(cnt) // 5
Johnny Morrice http://jmorrice.teoma.io http://github.com/johnny-morrice
Working on this today, I realised that shelling out has many of the same problems as RPC. Even though it's a lot simpler.
The core issue is that serializing/deserializing over process/language/codebase boundaries is difficult.
Let's face it: fractal fans have already written all kinds of toy renderers. They aren't going to rearchitect their systems to match Godelbrot's expectations. They aren't going to learn Golang. They don't want to pollute their $PATH or their network with wrappers/shims/DCOM style RPC bollocks.
Godelbrot will embed Lua.
A plugin is a Lua function that receives an object representation of Godelbrot's json config format.
Plugin discovery is Lua namespace.
The function writes the fractal render image to stdout and any warnings or errors to stderr.
The Lua function must return an error code.
Plugin authors are free to shell out from Lua to invoke their program, or a shim that calls their service, or or or or....
While godelbrot is flexible in terms of its internal engineering, for true flexibility fractal render algorithms ought to be external code that implement a plugin interface.
A likely plugin provider is
https://github.com/hashicorp/go-plugin
We assume in any case where the user is getting bored, the complexity of rendering a fractal dwarfs the time to copy output over the loopback interface. :)