如何卸载已加载的Go插件1.8?

huangapple go评论89阅读模式
英文:

golang: how to unload an already loaded "go plugin" 1.8

问题

从Go 1.8开始,Go语言支持创建和加载插件。

但是,不支持卸载插件。

插件是在运行时加载的模块,是否可能卸载一个模块?

如果无法卸载模块,那么在应用程序级别上,如何使插件无法使用但仍保留在内存中是最好的解决方案?

英文:

go1.8 onwards, go supports to create and load a plugin.

but unload plugin is not supported.

a plugin is a module loaded at runtime, is it possible to unload a module?

if not possible to unload a module, what is the best that can be done at application level to unload a plugin/make it unusable but still in memory?

答案1

得分: 1

Go语言不支持卸载插件,但你可以像你建议的那样禁用它。通常,插件会定义一个包含有关插件信息的结构体。你可以从一个名字已知的工厂函数中返回这个结构体(例如,awesome.so 包含 AwesomePlugin)。在结构体中,你可以包含一个禁用插件访问的方法。你可以这样做:

type MyPlugin struct {
    Name    string
    Enable  func() error
    Disable func() error
}

然后,在插件本身中,你可以这样做:

var (
    awesomeEnabled bool
)

func AwesomePlugin() *myplugin.MyPlugin {
    return &myplugin.MyPlugin{
        Name: "AwesomePlugin",
        Enable: func() error {
            println("Enabling AwesomePlugin")
            awesomeEnabled = true
            return nil // or do something more complex that could error
        },
        Disable: func() error {
            println("Disabling AwesomePlugin")
            awesomeEnabled = false
            return nil // or do something more complex that could error
        },
    }
}

然后,加载、启用和禁用插件的代码将如下所示:

awesomePlugin, err := plugin.Open("awesome.so")
if err != nil {
    panic("Can't load plugin: " + err.Error())
}

sym, err := awesomePlugin.Lookup("AwesomePlugin")
if err != nil {
    panic("Can't find symbol: " + err.Error())
}

awesomeFactory := sym.(func() *myplugin.MyPlugin)
awesome := awesomeFactory()

println("Loaded " + awesome.Name + " plugin")

err = awesome.Enable()
if err != nil {
    panic("Can't enable plugin: " + err.Error())
}

// Do some stuff

err = awesome.Disable()
if err != nil {
    panic("Can't enable plugin: " + err.Error())
}

在运行之前,插件中的代码会查看插件是否已启用,然后再运行其他你可能定义的函数。

然后,运行代码,我们会得到如下输出:

Loaded AwesomePlugin plugin
Enabling AwesomePlugin
Disabling AwesomePlugin

显然,你不希望在各个地方都使用 panic()。那只是一个用于处理错误的占位符。

英文:

Go doesn't support unloading a plugin. But you can, as you suggest, disable it. Commonly a plugin would define a struct containing the information about the plugin. You might return this from a factory function with a well-known name (e.g. awesome.so contains AwesomePlugin). One of the items you could include in the struct would be a method to disable access to the plugin. You could do something like this:

type MyPlugin struct {
	Name string
	Enable func() error
	Disable func() error
}

Then in the plugin itself you'd do something like this:

var (
	awesomeEnabled bool
)

func AwesomePlugin() *myplugin.MyPlugin {
	return &myplugin.MyPlugin{
		Name: "AwesomePlugin",
		Enable: func() error {
			println("Enabling AwesomePlugin")
			awesomeEnabled = true
			return nil // or do something more complex that could error
		},
		Disable: func() error {
			println("Disabling AwesomePlugin")
			awesomeEnabled = false
			return nil // or do something more complex that could error
		},
	}
}

Then the code to load it, enable it, and disable it would be something like:

awesomePlugin, err := plugin.Open("awesome.so")
if err != nil {
	panic("Can't load plugin: " + err.Error())
}

sym, err := awesomePlugin.Lookup("AwesomePlugin")
if err != nil {
	panic("Can't find symbol: " + err.Error())
}

awesomeFactory := sym.(func() *myplugin.MyPlugin)
awesome := awesomeFactory()

println("Loaded " + awesome.Name + " plugin")

err = awesome.Enable()
if err != nil {
	panic("Can't enable plugin: " + err.Error())
}

// Do some stuff

err = awesome.Disable()
if err != nil {
	panic("Can't enable plugin: " + err.Error())
}

You'd have the code in the plugin look to see if the plugin is enabled or not before running any other functions you might define.

Then, running it, we get output like:

Loaded AwesomePlugin plugin
Enabling AwesomePlugin
Disabling AwesomePlugin

Obviously you don't want to panic() everywhere. That's just a placeholder for doing something with the error.

huangapple
  • 本文由 发表于 2017年4月13日 00:43:32
  • 转载请务必保留本文链接:https://go.coder-hub.com/43375234.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定