func (p *plugin) kill(wg *sync.WaitGroup) error { defer wg.Done() if p.IsProcessRunning() { defer p.connection.Close() conn.SendProcessKillMessage(p.connection) exited := make(chan bool, 1) go func() { for { if p.IsProcessRunning() { time.Sleep(100 * time.Millisecond) } else { exited <- true return } } }() select { case done := <-exited: if done { logger.Debug("Plugin [%s] with pid [%d] has exited", p.descriptor.Name, p.pluginCmd.Process.Pid) } case <-time.After(config.PluginConnectionTimeout()): logger.Warning("Plugin [%s] with pid [%d] did not exit after %.2f seconds. Forcefully killing it.", p.descriptor.Name, p.pluginCmd.Process.Pid, config.PluginConnectionTimeout().Seconds()) err := p.pluginCmd.Process.Kill() if err != nil { logger.Warning("Error while killing plugin %s : %s ", p.descriptor.Name, err.Error()) } return err } } return nil }
func (plugin *plugin) kill(wg *sync.WaitGroup) error { defer wg.Done() if plugin.isStillRunning() { exited := make(chan bool, 1) go func() { for { if plugin.isStillRunning() { time.Sleep(100 * time.Millisecond) } else { exited <- true return } } }() select { case done := <-exited: if done { logger.Log.Debug("Plugin [%s] with pid [%d] has exited", plugin.descriptor.Name, plugin.pluginCmd.Process.Pid) } case <-time.After(config.PluginConnectionTimeout()): logger.Log.Warning("Plugin [%s] with pid [%d] did not exit after %.2f seconds. Forcefully killing it.", plugin.descriptor.Name, plugin.pluginCmd.Process.Pid, config.PluginConnectionTimeout().Seconds()) return plugin.pluginCmd.Process.Kill() } } return nil }
func startPluginsForExecution(manifest *manifest.Manifest) (*Handler, []string) { var warnings []string handler := &Handler{} envProperties := make(map[string]string) for _, pluginID := range manifest.Plugins { pd, err := GetPluginDescriptor(pluginID, "") if err != nil { warnings = append(warnings, fmt.Sprintf("Error starting plugin %s. Failed to get plugin.json. %s. To install, run `gauge --install %s`.", pluginID, err.Error(), pluginID)) continue } compatibilityErr := version.CheckCompatibility(version.CurrentGaugeVersion, &pd.GaugeVersionSupport) if compatibilityErr != nil { warnings = append(warnings, fmt.Sprintf("Compatible %s plugin version to current Gauge version %s not found", pd.Name, version.CurrentGaugeVersion)) continue } if isExecutionScopePlugin(pd) { gaugeConnectionHandler, err := conn.NewGaugeConnectionHandler(0, nil) if err != nil { warnings = append(warnings, err.Error()) continue } envProperties[pluginConnectionPortEnv] = strconv.Itoa(gaugeConnectionHandler.ConnectionPortNumber()) err = SetEnvForPlugin(executionScope, pd, manifest, envProperties) if err != nil { warnings = append(warnings, fmt.Sprintf("Error setting environment for plugin %s %s. %s", pd.Name, pd.Version, err.Error())) continue } plugin, err := StartPlugin(pd, executionScope) if err != nil { warnings = append(warnings, fmt.Sprintf("Error starting plugin %s %s. %s", pd.Name, pd.Version, err.Error())) continue } pluginConnection, err := gaugeConnectionHandler.AcceptConnection(config.PluginConnectionTimeout(), make(chan error)) if err != nil { warnings = append(warnings, fmt.Sprintf("Error starting plugin %s %s. Failed to connect to plugin. %s", pd.Name, pd.Version, err.Error())) plugin.pluginCmd.Process.Kill() continue } plugin.connection = pluginConnection handler.addPlugin(pluginID, plugin) } } return handler, warnings }