
Golang Package: plugin - pythonist
https://tip.golang.org/pkg/plugin/
======
guessmyname
I agree with this comment from Reddit four days ago:

> The inability to unload a plugin defeats the use I would have for this,
> unfortunately. A long running service with plugins may want to load new,
> updated versions of an existing plugin. Not being able to unload the old
> version, ends up creating stale references which will keep piling up for the
> lifetime of the process. As I understand it, this is essentially a memory
> leak. [...]

>
> [https://www.reddit.com/r/golang/comments/53adu8/a/d7rmmco](https://www.reddit.com/r/golang/comments/53adu8/a/d7rmmco)

There is also this project by Hashicorp: [https://github.com/hashicorp/go-
plugin](https://github.com/hashicorp/go-plugin)

------
zupa-hu
Amazing, so this is essentially a high performance alternative to Go
scripting. One can already include the go build toolchain in a binary, right?
Having JIT is only small steps away.

Disagree with the problem of unloading plugins. From the sizes of Go binaries
and memory sizes, one could easily load 10k+ plugins before the process needed
a restart. Would be nice to have GC, but having plugins is such an increased
benefit. To me this sounds like, Git is crap because you can't unload stored
objects.

------
pjmlp
Nice to see this coming, one step closer to have Oberon System 3 with Gadgets
rewritten in Go. :)

------
gtrubetskoy
Curious what it would take (if at all possible?) to load such a .so from C.
Because that would open the door for writing Go libs for all your favorite
interpreted languages, web servers, etc.

~~~
dvirsky
That's already possible, I've written an API that encapsulates Go libraries as
Redis modules.

~~~
Goopplesoft
Link?

~~~
dvirsky
It's a WIP and I haven't had the time to complete it, but here it is. You can
load modules, handle redis commands and return responses, but you can't access
redis itself yet.

[https://github.com/RedisLabs/rgm/blob/master/example/module....](https://github.com/RedisLabs/rgm/blob/master/example/module.go)

------
orta
This is awesome, a plugin structure like this is one of the fundamentals of
macOS programming (they're called NSBundles in those cases.)

------
junke
> A plugin is only initialized once, and cannot be closed.

Why not?

~~~
IshKebab
I guess it's because if you load a symbol there's no clean way to invalidate
it, especially in a thread-safe way. Something like that anyway.

~~~
jerf
I think it's safe to say there is just plain no way to invalidate it. Even if
it were hacked together, it would be unusably dangerous for even trivial
cases.

Module loading is something that can be added to a language later, but I
suspect safe module _unloading_ is something that has to go in from day one to
ever work right. Even in languages that support it (Erlang) it's got a tricky
list of caveats to keep track of that strike me as fairly essential to the
problem, rather than accidental (in the Fred Brooks sense of the terms).

------
speps
I see an API fail coming. It seems plugin.Load takes the filename WITH
extension where it shouldn't. Okay, right now it seems it's only supported on
Linux but it ends up in Windows, you'd have to patch code to remove the .so.
Mono handles it pretty well, the extension is optional.

~~~
IshKebab
I don't think so. I think it is better that the file naming is handled in the
application. It is less restrictive, e.g. you can use custom extensions this
way.

Consider another instance where file names are automatically mangled: GCC
linking with libraries with the switch -lfoo. That has honestly caused me no
end of problems. It would have been better if they required an explicit
-llibfoo.so from the start.

Go already has several easy methods for OS-specific code if you want.

~~~
dvirsky
Not sure it should be be part of this package, but it's trivial to write a
function that exposes something like "SharedLibraryFile(libname string)
string". Depending on the OS it just formats the default shared object name.

For extra runtime speed you could build OS specific versions of that function
using build flags, so for each target OS it has one implementation and you
have no switch/case or anything in runtime.

------
SoapSeller
Didn't one of the main selling points of Go is one big static executable with
no external dependencies?

What's next? Generics?

~~~
dvirsky
Although this can be abused, the use case is not external dependencies IMO,
but rather extending systems. Think of a web server etc. Each plugin is still
a static binary that is self contained, but you can load capabilities into the
server in runtime.

This is not like dynamic linking hell you can get yourself into when writing
C.

~~~
wtbob
> Each plugin is still a static binary that is self contained, but you can
> load capabilities into the server in runtime.

In my Go code, I've just used subprocesses for that. Stdin & stdout, plus a
simple serialisation format, and I'm done.

Not suitable for high performance stuff, of course, but good enough for my
needs.

~~~
dvirsky
yeah, it could work for sure if latency is not an issue. It's also possible to
do a go->C->go bridge to load Go plugins dynamically.

