// Main serves the given plugin. It is the entry point to the plugin system. // User-defined plugins should call Main with their main function. // // func main() { // plugin.Main(myPlugin) // } func Main(p *Plugin) { if p.Name == "" { panic("a plugin name must be provided") } // The plugin communicates with the ThriftRW process over stdout and stdin // of this process. Requests and responses are Thrift envelopes with a // 4-byte big-endian encoded length prefix. Envelope names contain method // names prefixed with the service name and a ":". mainHandler := multiplex.NewHandler() features := []api.Feature{} if p.ServiceGenerator != nil { features = append(features, api.FeatureServiceGenerator) mainHandler.Put("ServiceGenerator", api.NewServiceGeneratorHandler(p.ServiceGenerator)) } // TODO(abg): Check for other features and register handlers here. server := frame.NewServer(_in, _out) mainHandler.Put("Plugin", api.NewPluginHandler(pluginHandler{ server: server, plugin: p, features: features, })) if err := server.Serve(envelope.NewServer(_proto, mainHandler)); err != nil { log.Fatalf("plugin server failed with error: %v", err) } }
func newFakePluginServer(mockCtrl *gomock.Controller) *fakePluginServer { serverReader, clientWriter := io.Pipe() clientReader, serverWriter := io.Pipe() server := frame.NewServer(serverReader, serverWriter) client := frame.NewClient(clientWriter, clientReader) mockPlugin := plugintest.NewMockPlugin(mockCtrl) mockServiceGenerator := plugintest.NewMockServiceGenerator(mockCtrl) handler := multiplex.NewHandler() handler.Put("Plugin", api.NewPluginHandler(mockPlugin)) handler.Put("ServiceGenerator", api.NewServiceGeneratorHandler(mockServiceGenerator)) done := make(chan error) go func() { err := server.Serve(envelope.NewServer(protocol.Binary, handler)) if err != nil { done <- err } close(done) }() return &fakePluginServer{ errCh: done, server: server, ClientTransport: client, Plugin: mockPlugin, ServiceGenerator: mockServiceGenerator, } }