glean

package module
v0.0.0-...-347efd9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 28, 2018 License: Apache-2.0 Imports: 10 Imported by: 0

README

Glean

A go plugin framework that can reload variables and functions from plugins automatically.

License GoDoc travis Go Report Card

Installation

go get -u github.com/smallnest/glean

Feature

  • load symbol and you don't worry about errors
  • load/reload exported variables and funtions from plugins
  • watch plugins' changes and reload pointer of variables and function in applications

Notice glean only can reload functions or variables that can be addresses.

Examples

see Examples

Let's look the httpserver example to learn how to use glean.

httpserver

httpserver is a very very simple http server.

A simple http server is just like this:

var FooHandler = func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello, world")
}

http.Handle("/foo", fooHandler)

log.Fatal(http.ListenAndServe(":9988", nil))

Our goal is to replace fooHandler with latest code dynamically (hot fix).

var FooHandler = func(w http.ResponseWriter, r *http.Request) {
	fmt.Fprint(w, "Hello, gp")
}

No need to restart this server.

step1: build the two plugin

enter _example/httpserver/plugins/plugin1 and _example/httpserver/plugins/plugin2, and run the build.sh to generate the so file.

Currently plugin supports linux and MacOS.

step2: modify the server implementation

package main

import (
	"log"
	"net/http"

	"github.com/smallnest/glean"
)

func main() {
	g := glean.New("plugin.json")
	err := g.LoadConfig()
	if err != nil {
		panic(err)
	}

	var fooHandler func(w http.ResponseWriter, r *http.Request)

	err = g.ReloadAndWatch("FooHandlerID", &fooHandler)

	if err != nil {
		panic(err)
	}

	http.HandleFunc("/foo", WarpFuncPtr(&fooHandler))

	log.Fatal(http.ListenAndServe(":9988", nil))
}

func WarpFuncPtr(fn *func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
	return func(w http.ResponseWriter, r *http.Request) {
		(*fn)(w, r)
	}
}

Firstly create the Glean instance and load config from given file. And then use ReloadAndWatch to load fooHandler and begin to watch its changes. At last use WarpFuncPtr to wrap fooHandler as a HandleFunc.

Run go run main.go to start this server, use a browser to visit "http://locakhost:9988/foo" and you will see hello world

Change the config file plugin.json and replace "file": "plugins/plugin1/plugin1.so" with :

"file": "plugins/plugin2/plugin2.so",

Browser the prior location and you will see hello gp.

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrItemHasNotConfigured the plugin item has not been configured.
	ErrItemHasNotConfigured = errors.New("pluginItem is not configured")
	// ErrClosed glean instance has been closed.
	ErrClosed = errors.New("glean has been closed")
	// ErrValueCanNotSet the object can not be set. See https://golang.org/pkg/reflect/#Value.CanSet.
	ErrValueCanNotSet = errors.New("the object can't be addressable and can not be set")
	// ErrMustBePointer the object (function or variable) must be pointer.
	ErrMustBePointer = errors.New("the function or variable must be pointer")
)

Functions

func LoadSymbol

func LoadSymbol(so, name string) (interface{}, error)

LoadSymbol loads a plugin and gets the symbol. It encapsulates plugin.Open and plugin.Lookup methods to a convenient function. so is file path of the plugin and name is the symbol.

func Reload

func Reload(so, name string, vPtr interface{}) error

Reload loads a function or a variable from the plugin and replace passed function or variable. If fails to load, the original function or variable won't be replaced.

func ReloadFromPlugin

func ReloadFromPlugin(p *plugin.Plugin, name string, vPtr interface{}) error

ReloadFromPlugin is like Reload but it loads a function or a variable from the given *plugin.Plugin.

Types

type Glean

type Glean struct {
	// contains filtered or unexported fields
}

Glean is a manager that manages all configured plugins and reloaded objects.

func New

func New(configFile string) *Glean

New returns a new Glean.

func (*Glean) Close

func (g *Glean) Close()

Close closes Glean and stop watching.

func (*Glean) FindAllPlugins

func (g *Glean) FindAllPlugins(t reflect.Type) ([]string, error)

FindAllPlugins gets all IDs that implements interface t.

func (*Glean) GetObjectByID

func (g *Glean) GetObjectByID(id string) (v interface{})

GetObjectByID gets the variable or function by ID.

func (*Glean) GetSymbolByID

func (g *Glean) GetSymbolByID(id string) (v interface{}, err error)

GetSymbolByID gets the variable or function by ID from cached plugin.

func (*Glean) LoadConfig

func (g *Glean) LoadConfig() (err error)

LoadConfig loads plugins from the configured file.

func (*Glean) Reload

func (g *Glean) Reload(id string, vPtr interface{}) error

Reload loads an variable or function from configured plugins.

func (*Glean) ReloadAndWatch

func (g *Glean) ReloadAndWatch(id string, vPtr interface{}) error

ReloadAndWatch loads an variable or function from plugins and begin to watch.

func (*Glean) Watch

func (g *Glean) Watch(id string, vPtr interface{})

Watch watches plugin changes and reload given function/variable automatically.

type PluginItem

type PluginItem struct {
	// File file path of this plugin.
	File string `json:"file"`
	// ID is an unique string for this item.
	ID string `json:"id"`
	// Name is name of the symbol. Notice id is unique but names may be duplicated in different plugins.
	Name string `json:"name"`
	// Version is version of the plugin for tracing and upgrade.
	Version string `json:"version"`
	// Cached points the opened plugin.
	Cached *plugin.Plugin `json:"-"`
	// contains filtered or unexported fields
}

PluginItem is a configured item that can be reloaded.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL