iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > GO >如何解决Golang库插件注册加载机制的问题
  • 525
分享到

如何解决Golang库插件注册加载机制的问题

2023-06-29 17:06:56 525人浏览 独家记忆
摘要

这篇文章主要介绍如何解决golang库插件注册加载机制的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!最近看到一个内部项目的插件加载机制,非常赞。当然这里说的插件并不是指的Golang原生的可以在buildmod

这篇文章主要介绍如何解决golang插件注册加载机制的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!

最近看到一个内部项目的插件加载机制,非常赞。当然这里说的插件并不是指的Golang原生的可以在buildmode中加载指定so文件的那种加载机制。而是软件设计上的「插件」。如果你的软件是一个框架,或者一个平台性产品,想要提升扩展性,即可以让第三方进行第三方库开发,最终能像搭积木一样将这些库组装起来。那么就可能需要这种库加载机制。

我们的目标是什么?对第三方库进行某种库规范,只要按照这种库规范进行开发,这个库就可以被加载到框架中。

我们先定义一个插件的数据结构,这里肯定是需要使用接口来规范,这个可以根据你的项目自由发挥,比如我希望插件有一个Setup方法来在启动的时候加载即可。然后我就定义如下的Plugin结构。

type Plugin interface{  Name() string  Setup(config map[string]string) error}

而在框架启动的时候,我启动了一个如下的全局变量:

var plugins map[string]Plugin

注册

有人可能会问,这里有了加载函数setup,但是为什么没有注册逻辑呢?

答案是注册的逻辑放在库的init函数中。

即框架还提供了一个注册函数。

// package pluginReGISter(plugin Plugin)

这个register就是实现了将第三方plugin放到plugins全局变量中。

所以第三方的plugin库大致实现如下:

package MyPlugintype MyPlugin struct{}func (m *MyPlugin) Setup(config map[string]string) error {// TODOfunc (m *MyPlugin) Name() string {return "myPlugin"func init() {plugin.Register(&MyPlugin)

这样注册的逻辑就变成了,如果你要加载一个插件,那么你在main.go中直接以 _ import的形式引入即可。

package main_ import "GitHub.com/foo/myplugin"func main() {}

整体的感觉,这样子插件的注册就被“隐藏”到import中了。

加载

注册的逻辑其实看起来也平平无奇,但是加载的逻辑就考验细节了。

首先插件的加载其实有两点需要考虑:

  • 配置

  • 依赖

配置指的是插件一定是有某种配置的,这些配置以配置文件yaml中plugins.myplugin的路径存在。

plugins:myplugin:foo: bar

其实我对这种实现持保留意见。配置文件以一个文件中配置项的形式存在,好像不如以配置文件的形式存在,即以config/plugins/myplugin.yaml 的文件。

这样不会出现一个大配置文件的问题。毕竟每个配置文件本身就是一门DSL语言。如果你将配置文件的逻辑变复杂,一定会有很多附带的bug是由于配置文件错误导致的。

第二个说的是依赖。插件A依赖与插件B,那么这里就有加载函数Setup的先后顺序了。这种先后顺序如果纯依赖用户的“经验”,将某个插件的Setup调用放在某个插件的Setup调用之前,是非常痛苦的。(虽然一定是有办法可以做到)。更好的办法是依赖于框架自身的加载机制来进行加载。

首先我们在plugin包中定义一个接口:

type Depend interface{DependOn() []string}

如果我的插件依赖一个名字为 “fooPlugin” 的插件,那么我的插件 MyPlugin就会实现这个接口。

package MyPlugintype MyPlugin struct{}func (m *MyPlugin) Setup(config map[string]string) error {// TODOfunc (m *MyPlugin) Name() string {return "myPlugin"func init() {plugin.Register(&MyPlugin)func (m *MyPlugin) DependOn() []string {return []string{"fooPlugin"}

在最终加载所有插件的时候,我们并不是简单地将所有插件调用Setup,而是使用一个channel,将所有插件放在channel中,然后一个个调用Setup,遇到有Depend其他插件的,且依赖插件还未被加载,则将当前插件放在队列最后(重新塞入channel)。

var setupStatus map[string]bool// 获取所有注册插件func loadPlugins() (plugin chan Plugin, setupStatus map[string]bool) {// 这里定义一个长度为10的队列var sortPlugin = make(chan Plugin, 10)var setupStatus = make[string]bool// 所有的插件for name, plugin := range plugins {sortPlugin <- pluginsetupStatus[name] = false}return sortPlugin, setupStatus}// 加载所有插件func SetupPlugins(pluginChan chan Plugin, setupStatus map[string]bool) error {num := len(pluginChan)for num > 0 {plugin <- pluginChancanSetup := trueif deps, ok := p.(Depend); ok {depends := deps.DependOn()for _, dependName := range depends{if _, setuped := setupStatus[dependName]; !setup {// 有未加载的插件canSetup = falsebreak}}}// 如果这个插件能被setupif canSetup {plugin.Setup(xxx)setupStatus[p.Name()] = true} else {// 如果插件不能被setup, 这个plugin就塞入到最后一个队列pluginChan <- pluginreturn nil}

上面这段代码最精妙的就是使用了一个有buffer的channel作为一个队列,消费队列一方SetupPlugins,除了消费队列,也有可能生产数据到队列,这样就保证了队列中所有plugin都是被按照标记的依赖被顺序加载的。

以上是“如何解决Golang库插件注册加载机制的问题”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注编程网GO频道!

您可能感兴趣的文档:

--结束END--

本文标题: 如何解决Golang库插件注册加载机制的问题

本文链接: https://www.lsjlt.com/news/325833.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 如何解决Golang库插件注册加载机制的问题
    这篇文章主要介绍如何解决Golang库插件注册加载机制的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!最近看到一个内部项目的插件加载机制,非常赞。当然这里说的插件并不是指的golang原生的可以在buildmod...
    99+
    2023-06-29
  • Golang库插件注册加载机制的问题
    目录注册加载总结最近看到一个内部项目的插件加载机制,非常赞。当然这里说的插件并不是指的golang原生的可以在buildmode中加载指定so文件的那种加载机制。而是软件设计上的「插...
    99+
    2024-04-02
  • win10注册ocx加载失败如何解决
    出现Win10注册ocx加载失败的情况,可能是由于ocx文件缺失或者注册不正确引起的。可以尝试以下几种解决方法:1. 确认ocx文件...
    99+
    2023-09-09
    win10
  • php加载不了dll库问题如何解决
    这篇文章主要介绍“php加载不了dll库问题如何解决”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“php加载不了dll库问题如何解决”文章能帮助大家解决问题。首先,我们需要了解一些背景知识。DLL,...
    99+
    2023-07-05
  • 如何解决Vue中SSR组件加载问题
    这篇文章主要介绍如何解决Vue中SSR组件加载问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Node 端渲染提示 window/document 没有定义业务场景首先来看一个简单...
    99+
    2024-04-02
  • excel插件加载失败如何解决
    今天小编给大家分享一下excel插件加载失败如何解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。excel插件加载失败:使...
    99+
    2023-07-02
  • 如何解决预加载InstantClick的问题
    这篇文章主要介绍如何解决预加载InstantClick的问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!在改造的时候代码高亮没法执行,准确的说是只执行一次,第二次就不执行了。所以发...
    99+
    2024-04-02
  • 如何解决VB.NET注册表权限问题
    这篇文章主要介绍如何解决VB.NET注册表权限问题,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!本实例需要项目引用:Imports Microsoft.Win32  '用途&nb...
    99+
    2023-06-17
  • 如何解决hibernate一对多注解懒加载失效问题
    目录hibernate一对多注解懒加载失效经排查,问题出在controller这边解决方法Hibernate懒加载异常说明及其解决懒加载异常出现的原因解决方案1解决方案2解决方案3h...
    99+
    2024-04-02
  • 解决jupyter加载文件失败的问题
    遇到个小白常见的问题,发现度娘里面没有记录,翻墙谷歌了下,解决问题,在此写个说明。 事情起因: 在jupyter notebook中导入文件时发生了错误: %load p2_te...
    99+
    2024-04-02
  • 如何解决swiper插件在H5下的问题
    这篇文章将为大家详细讲解有关如何解决swiper插件在H5下的问题,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。最近在做H5页面的时候用到swiper.js这个轮播插件,...
    99+
    2024-04-02
  • 如何解决SpringCloud服务注册IP错误的问题
    这篇文章主要介绍“如何解决SpringCloud服务注册IP错误的问题”,在日常操作中,相信很多人在如何解决SpringCloud服务注册IP错误的问题问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”如何解决S...
    99+
    2023-06-20
  • vue如何解决数据加载时,插值表达式闪烁问题
    目录数据加载,插值表达式闪烁问题1.在公共的css样式中加入2.在el挂载的标签上添加解决插值表达式渲染数据闪动先看代码出现的问题解决方法如下图数据加载,插值表达式闪烁问题 1.在公...
    99+
    2024-04-02
  • 如何解决网站加载速度问题
    解决网站加载速度问题的关键措施包括:1、优化图片和多媒体文件,2、使用内容分发网络(CDN),3、压缩和优化代码,4、减少HTTP请求,5、启用浏览器缓存。网站加载速度对于用户体验和搜索引擎排名都至关重要。通过执行这些措施,你可以显著提高网...
    99+
    2023-10-29
    如何解决 加载 速度
  • Pycharm挂代理后依旧插件下载慢的问题如何解决
    这篇文章主要讲解了“Pycharm挂代理后依旧插件下载慢的问题如何解决”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Pycharm挂代理后依旧插件下载慢的问题如何解决”吧!首先要挂代理,但是...
    99+
    2023-06-20
  • jquery touch事件注册不了的问题怎么解决
    今天小编给大家分享一下jquery touch事件注册不了的问题怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。随着移...
    99+
    2023-07-06
  • 如何解决.cuda()加载用时很长的问题
    方法一: pip install --upgrade --force-reinstall http://download.pytorch.org/whl/cu80/torch-0...
    99+
    2024-04-02
  • PHP在Linux中的加载问题该如何解决?
    PHP作为一门流行的编程语言,已经成为了许多网站和应用程序的首选语言。在Linux操作系统中,PHP的加载问题是一个常见的挑战。在本文中,我们将探讨PHP在Linux中的加载问题,并提供一些解决方法。 PHP加载问题的原因 在Linu...
    99+
    2023-11-04
    load linux linux
  • 如何解决ionic和angular上拉加载的问题
    这篇文章主要介绍了如何解决ionic和angular上拉加载的问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。说到ionic上拉加载就跟p...
    99+
    2024-04-02
  • 如何解决vue页面加载闪烁的问题
    这篇文章主要介绍了如何解决vue页面加载闪烁的问题,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。v-if 和 v-show 的区别v-if只...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作