func (l *loader) call(object string) error {
	p, err := plugin.Open(object)
	if err != nil {
		return fmt.Errorf("could not open %s: %v", object, err)
	}
	run, err := p.Lookup("Run")
	if err != nil {
		return fmt.Errorf("could not find Run function: %v", err)
	}
	runFunc, ok := run.(func() error)
	if !ok {
		return fmt.Errorf("found Run but type is %T instead of func() error", run)
	}
	if err := runFunc(); err != nil {
		return fmt.Errorf("plugin failed with error %v", err)
	}
	return nil
}
call loads the plugin object in the given path and runs the Run
function.
package main
import (
	"fmt"
	"io/ioutil"
	"log"
	"math/rand"
	"os"
	"os/exec"
	"path/filepath"
	"plugin"
)
func main() {
	l, err := newLoader()
	if err != nil {
		fmt.Fprintf(os.Stderr, "%v", err)
		os.Exit(2)
	}
	defer l.destroy()
	for {
		for _, name := range l.plugins() {
			if err := l.compileAndRun(name); err != nil {
				fmt.Fprintf(os.Stderr, "%v", err)
			}
		}
	}
}
type loader struct {
	pluginsDir string
	objectsDir string
}
func newLoader() (*loader, error) {
	wd, err := os.Getwd()
	if err != nil {
		return nil, fmt.Errorf("could not find current directory: %v", err)
	}
	pluginsDir := filepath.Join(wd, "plugins")
	tmp, err := ioutil.TempDir("", "")
	if err != nil {
		return nil, fmt.Errorf("could not create objects dir: %v", err)
	}
	return &loader{pluginsDir: pluginsDir, objectsDir: tmp}, nil
}
func (l *loader) destroy() { os.RemoveAll(l.pluginsDir) }
func (l *loader) compileAndRun(name string) error {
	obj, err := l.compile(name)
	if err != nil {
		return fmt.Errorf("could not compile %s: %v", name, err)
	}
	defer os.Remove(obj)
	if err := l.call(obj); err != nil {
		return fmt.Errorf("could not run %s: %v", obj, err)
	}
	return nil
}
func (l *loader) compile(name string) (string, error) {
	f, err := ioutil.ReadFile(filepath.Join(l.pluginsDir, name))
	if err != nil {
		return "", fmt.Errorf("could not read %s: %v", name, err)
	}
	name = fmt.Sprintf("%d.go", rand.Int())
	srcPath := filepath.Join(l.objectsDir, name)
	if err := ioutil.WriteFile(srcPath, f, 0666); err != nil {
		return "", fmt.Errorf("could not write %s: %v", name, err)
	}
	objectPath := srcPath[:len(srcPath)-3] + ".so"
	cmd := exec.Command("go", "build", "-buildmode=plugin", "-o="+objectPath, srcPath)
	cmd.Stderr = os.Stderr
	cmd.Stdout = os.Stdout
	if err := cmd.Run(); err != nil {
		return "", fmt.Errorf("could not compile %s: %v", name, err)
	}
	return objectPath, nil
}