From 535e8429e08bfc8c4c7bde3417bbd06c39e2bb83 Mon Sep 17 00:00:00 2001 From: Oleg Nenashev Date: Sat, 26 Nov 2016 20:43:39 +0100 Subject: [PATCH] Add extension point for tracking process startup and termination in extensions --- src/Core/ServiceWrapper/Main.cs | 2 + .../Extensions/AbstractWinSWExtension.cs | 10 +++++ .../WinSWCore/Extensions/IWinSWExtension.cs | 19 ++++++++- .../Extensions/WinSWExtensionManager.cs | 41 +++++++++++++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/src/Core/ServiceWrapper/Main.cs b/src/Core/ServiceWrapper/Main.cs index dd18771..dcfa141 100644 --- a/src/Core/ServiceWrapper/Main.cs +++ b/src/Core/ServiceWrapper/Main.cs @@ -269,6 +269,7 @@ namespace winsw WriteEvent("Starting " + _descriptor.Executable + ' ' + startarguments); StartProcess(_process, startarguments, _descriptor.Executable); + ExtensionManager.FireOnProcessStarted(_process); // send stdout and stderr to its respective output file. HandleLogfiles(); @@ -321,6 +322,7 @@ namespace winsw { WriteEvent("ProcessKill " + _process.Id); StopProcessAndChildren(_process.Id); + ExtensionManager.FireOnProcessTerminated(_process); } catch (InvalidOperationException) { diff --git a/src/Core/WinSWCore/Extensions/AbstractWinSWExtension.cs b/src/Core/WinSWCore/Extensions/AbstractWinSWExtension.cs index acba93c..d1b0c40 100644 --- a/src/Core/WinSWCore/Extensions/AbstractWinSWExtension.cs +++ b/src/Core/WinSWCore/Extensions/AbstractWinSWExtension.cs @@ -23,5 +23,15 @@ namespace winsw.Extensions { // Do nothing } + + public virtual void OnProcessStarted(System.Diagnostics.Process process) + { + // Do nothing + } + + public virtual void OnProcessTerminated(System.Diagnostics.Process process) + { + // Do nothing + } } } diff --git a/src/Core/WinSWCore/Extensions/IWinSWExtension.cs b/src/Core/WinSWCore/Extensions/IWinSWExtension.cs index c114381..f3e1ef1 100644 --- a/src/Core/WinSWCore/Extensions/IWinSWExtension.cs +++ b/src/Core/WinSWCore/Extensions/IWinSWExtension.cs @@ -9,7 +9,8 @@ namespace winsw.Extensions /// /// /// All implementations should provide the default empty constructor. - /// The initialization will be performed by Init methods + /// The initialization will be performed by Init methods. + /// Binary comparibility of the class is not guaranteed in WinSW 2. /// public interface IWinSWExtension { @@ -37,6 +38,22 @@ namespace winsw.Extensions /// Any error during execution void OnStart(IEventWriter logger); + /// + /// Handler, which is being invoked once the child process is started. + /// + /// Process + /// Logger + /// Any error during execution + void OnProcessStarted(System.Diagnostics.Process process); + + /// + /// Handler, which is being invoked once the child process is terminated. + /// + /// Process + /// Logger + /// Any error during execution + void OnProcessTerminated(System.Diagnostics.Process process); + /// /// Stop handler. Called during stop of the service /// diff --git a/src/Core/WinSWCore/Extensions/WinSWExtensionManager.cs b/src/Core/WinSWCore/Extensions/WinSWExtensionManager.cs index c305409..a82213a 100644 --- a/src/Core/WinSWCore/Extensions/WinSWExtensionManager.cs +++ b/src/Core/WinSWCore/Extensions/WinSWExtensionManager.cs @@ -4,6 +4,7 @@ using System.Xml; using System.Reflection; using System.Diagnostics; using winsw.Util; +using log4net; namespace winsw.Extensions { @@ -12,6 +13,8 @@ namespace winsw.Extensions public Dictionary Extensions { private set; get; } public ServiceDescriptor ServiceDescriptor { private set; get; } + private static readonly ILog Log = LogManager.GetLogger(typeof(WinSWExtensionManager)); + public WinSWExtensionManager(ServiceDescriptor serviceDescriptor) { ServiceDescriptor = serviceDescriptor; @@ -42,6 +45,44 @@ namespace winsw.Extensions } } + /// + /// Handler, which is being invoked once the child process is started. + /// + /// Process + public void FireOnProcessStarted(System.Diagnostics.Process process) + { + foreach (var ext in Extensions) + { + try + { + ext.Value.OnProcessStarted(process); + } + catch (ExtensionException ex) + { + Log.Error("onProcessStarted() handler failed for " + ext.Value.DisplayName, ex); + } + } + } + + /// + /// Handler, which is being invoked once the child process is terminated. + /// + /// Process + public void FireOnProcessTerminated(System.Diagnostics.Process process) + { + foreach (var ext in Extensions) + { + try + { + ext.Value.OnProcessTerminated(process); + } + catch (ExtensionException ex) + { + Log.Error("onProcessTerminated() handler failed for " + ext.Value.DisplayName, ex); + } + } + } + //TODO: Implement loading of external extensions. Current version supports internal hack #region Extension load management