GithubHelp home page GithubHelp logo

pingo's Introduction

Pingo: Plugins for Go

Pingo is a simple standalone library to create plugins for your Go program. As Go is statically linked, all plugins run as external processes.

The library aims to be as simple as possible and to mimic the standard RPC package to be immediately familiar to most developers.

Pingo supports both TCP and Unix as communication protocols. However, remote plugins are currently not supported. Remote plugins might be implemented if requested.

Example

Create a new plugin. Make a directory named after the plugin (for example plugins/hello-world) and write main.go as follows:

// Always create a new binary
package main

import "github.com/dullgiulio/pingo"

// Create an object to be exported
type MyPlugin struct{}

// Exported method, with a RPC signature
func (p *MyPlugin) SayHello(name string, msg *string) error {
    *msg = "Hello, " + name
    return nil
}

func main() {
	plugin := &MyPlugin{}

	// Register the objects to be exported
	pingo.Register(plugin)
	// Run the main events handler
	pingo.Run()
}

And compile it:

$ cd plugins/hello-world
$ go build

You should get an executable called hello-world. Congratulations, this is your plugin.

Now, time to use the newly create plugin.

In your main executable, invoke the plugin you have just created:

package main

import (
	"log"
	"github.com/dullgiulio/pingo"
)

func main() {
	// Make a new plugin from the executable we created. Connect to it via TCP
	p := pingo.NewPlugin("tcp", "plugins/hello-world/hello-world")
	// Actually start the plugin
	p.Start()
	// Remember to stop the plugin when done using it
	defer p.Stop()

	var resp string

	// Call a function from the object we created previously
	if err := p.Call("MyPlugin.SayHello", "Go developer", &resp); err != nil {
		log.Print(err)
	} else {
		log.Print(resp)
	}
}

Now, build your executable and all should work! Remember to use the correct path to your plugins when you make the Plugin object. Ideally, always pass an absolute path.

Unix or TCP?

When allocating a new plugin (via NewPlugin), you have to choose whether to use Unix or TCP.

In general, prefer Unix: it has way less overhead. However, if you choose Unix you should provide a writable directory where to place the temporary socket. Do so using SetSocketDirectory before you call Start.

If you do not specify a directory, the default temporary directory for your OS will be used. Note, however, that for security reasons, it might not be possible to create a socket there. It is advised to always specify a local directory.

Otherwise, the overhead of using TCP locally is negligible.

Your Pingo plugin will not accept non-local connections even via TCP.

Bugs

Report bugs in Github. Pull requests are welcome!

TODO

  • Automatically restart crashed plugins
  • Automatically switch between unix and TCP if setup of one fails

License

MIT

pingo's People

Contributors

dullgiulio avatar tcnksm avatar

Stargazers

 avatar Mason avatar Michaelyn avatar zhengkunwang avatar SimonQ avatar Enjoy avatar anthony gao avatar ibc789 avatar Dashuang avatar  avatar  avatar qianmianyao avatar rong fengliang avatar  avatar bitepeng avatar Zhang Jinlong avatar superwen avatar  avatar Richard avatar imcode avatar Gordon avatar Song Liu avatar Aioria avatar Kabochar avatar 长弓词 avatar  avatar 谷米万物 avatar demo avatar James Liu avatar  avatar Evan avatar longalong avatar Sany avatar  avatar 虫子樱桃 avatar  avatar George Wang avatar YouCanFly avatar HAYASAKA Ryosuke avatar Ariel Lahiany avatar Connard avatar 奇 avatar  avatar 何进 avatar BoyChai avatar  avatar  avatar jgbooks avatar  avatar Marvin Zhang avatar  avatar  avatar 许涛 avatar  avatar HuanLiu avatar  avatar DoNetKit avatar HeXiaodong avatar 知命 avatar Feng avatar  avatar Tsubasa SEKIGUCHI avatar  avatar Rick avatar star avatar Zhu avatar zhjrate avatar Boya Xiao avatar ddc avatar ff4415 avatar striveQiao avatar E024 avatar  avatar Alex louis avatar Andy avatar  avatar Oshine avatar haoran127 avatar  avatar Karen avatar SonWa avatar  avatar hunknownz avatar littleqiang avatar liangran avatar MakerYang avatar ᴍᴏᴏɴD4ʀᴋ avatar libz avatar fumeboy avatar  avatar  avatar Ray Guo avatar  avatar nobv avatar Masaki ISHIYAMA avatar  avatar Junpei Tsuji avatar iotserv avatar KevinLin avatar maplgebra avatar

Watchers

Henry Stamerjohann avatar Luka Napotnik avatar Mark Sta Ana avatar  avatar mayulu avatar kevin chen avatar  avatar James Cloos avatar Antonio Linari avatar 像树一样成长! avatar Takafumi Hirata avatar Neo Anderson avatar Zhongda avatar  avatar Kuzma Kuvardin avatar ieasydevops avatar  avatar zj8487 avatar ting avatar 张伯雨 avatar  avatar  avatar spcent avatar Michele D'Ascanio avatar  avatar  avatar  avatar  avatar  avatar

pingo's Issues

Pingo should support stdio as transport

Apart from Unix sockets and TCP, plugins should be able to use stdio for RPC. One major advantage is security.

See what the limitations are and how to approach this within the current structure (if possible, keep namespaces and other output from the plugin available to the plugin controller).

Abandon additional transport method parameter

Most of the time, users won't care what is the underlaying communication protocol.
So, I propose:

func NewPlugin(path string, params ...string) *Plugin

To change the default communication protocol, expose:

func SetProto(proto string)

The API becomes clearer. E.g.:

p := pingo.NewPlugin("plugins/hello-world/hello-world")

Pingo hijacks flags

If you use pingo in combination with a library that acts as a substitute for flags (e.g. cli ), the application flags get overriden by pingo's. This happens even if you just import pingo.

As far as I can tell, this is due to this line, in combination with pingo's use of flags in makeConfig().

Would you accept a PR that refactored to ensure pingo is side-effect-free, and that a configuration could be passed in?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.