github.com/getgauge/gauge@v1.6.9/plugin/handler.go (about) 1 /*---------------------------------------------------------------- 2 * Copyright (c) ThoughtWorks, Inc. 3 * Licensed under the Apache License, Version 2.0 4 * See LICENSE in the project root for license information. 5 *----------------------------------------------------------------*/ 6 7 package plugin 8 9 import ( 10 "sync" 11 12 "github.com/getgauge/gauge-proto/go/gauge_messages" 13 "github.com/getgauge/gauge/logger" 14 ) 15 16 // Handler manages plugins listed in project manifest. 17 type Handler interface { 18 NotifyPlugins(*gauge_messages.Message) 19 GracefullyKillPlugins() 20 } 21 22 // GaugePlugins holds a reference to all plugins launched. The plugins are listed in project manifest 23 type GaugePlugins struct { 24 pluginsMap map[string]*plugin 25 } 26 27 func (gp *GaugePlugins) addPlugin(pluginID string, pluginToAdd *plugin) { 28 if gp.pluginsMap == nil { 29 gp.pluginsMap = make(map[string]*plugin) 30 } 31 gp.pluginsMap[pluginID] = pluginToAdd 32 } 33 34 func (gp *GaugePlugins) removePlugin(pluginID string) { 35 delete(gp.pluginsMap, pluginID) 36 } 37 38 // NotifyPlugins passes a message to all plugins listed in the manifest 39 func (gp *GaugePlugins) NotifyPlugins(message *gauge_messages.Message) { 40 var handle = func(id string, p *plugin, err error) { 41 if err != nil { 42 logger.Errorf(true, "Unable to connect to plugin %s %s. %s\n", p.descriptor.Name, p.descriptor.Version, err.Error()) 43 gp.killPlugin(id) 44 } 45 } 46 47 for id, plugin := range gp.pluginsMap { 48 handle(id, plugin, plugin.sendMessage(message)) 49 } 50 } 51 52 func (gp *GaugePlugins) killPlugin(pluginID string) { 53 plugin := gp.pluginsMap[pluginID] 54 logger.Debugf(true, "Killing Plugin %s %s\n", plugin.descriptor.Name, plugin.descriptor.Version) 55 err := plugin.pluginCmd.Process.Kill() 56 if err != nil { 57 logger.Errorf(true, "Failed to kill plugin %s %s. %s\n", plugin.descriptor.Name, plugin.descriptor.Version, err.Error()) 58 } 59 gp.removePlugin(pluginID) 60 } 61 62 // GracefullyKillPlugins tells the plugins to stop, letting them cleanup whatever they need to 63 func (gp *GaugePlugins) GracefullyKillPlugins() { 64 var wg sync.WaitGroup 65 for _, pl := range gp.pluginsMap { 66 wg.Add(1) 67 logger.Debugf(true, "Sending kill message to %s plugin.", pl.descriptor.Name) 68 go func(p *plugin) { 69 err := p.kill(&wg) 70 if err != nil { 71 logger.Errorf(false, "Unable to kill plugin %s : %s", p.descriptor.Name, err.Error()) 72 } 73 }(pl) 74 } 75 wg.Wait() 76 }