Skip to content

Commit

Permalink
fixes the service recovery delay configuration bug.
Browse files Browse the repository at this point in the history
  • Loading branch information
paulomorgado authored and phatboyg committed Sep 19, 2018
1 parent 45bb363 commit 5a22972
Show file tree
Hide file tree
Showing 10 changed files with 161 additions and 27 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,6 @@ public static IEnumerable<Option> Parse(this IConfigurationSection configuration
var account = configuration.GetSection("Account");
var accountValue = account.Value;


if (string.Equals(accountValue, "LocalSystem", StringComparison.OrdinalIgnoreCase))
{
options.Add(new LocalSystemOption());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,17 @@ namespace Topshelf.HostConfigurators
using Configurators;

/// <summary>
/// Can configure/replace the input HostBuilder, returning the original
/// or a new HostBuilder
/// Can configure/replace the input <see cref="HostBuilder"/>, returning the original
/// or a new <see cref="HostBuilder"/>.
/// </summary>
public interface HostBuilderConfigurator :
Configurator
{
/// <summary>
/// Configures the host builder.
/// </summary>
/// <param name="builder">The host builder.</param>
/// <returns>The configured host builder.</returns>
HostBuilder Configure(HostBuilder builder);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@ namespace Topshelf.HostConfigurators
using Runtime;
using Runtime.Windows;

/// <summary>
/// Implements a service recovery configurator and host builder configurator.
/// </summary>
/// <seealso cref="Topshelf.ServiceRecoveryConfigurator" />
/// <seealso cref="Topshelf.HostConfigurators.HostBuilderConfigurator" />
public class ServiceRecoveryHostConfigurator :
ServiceRecoveryConfigurator,
HostBuilderConfigurator
Expand All @@ -40,6 +45,12 @@ public IEnumerable<ValidateResult> Validate()
}
}

/// <summary>
/// Configures the host builder.
/// </summary>
/// <param name="builder">The host builder.</param>
/// <returns>The configured host builder.</returns>
/// <exception cref="ArgumentNullException">builder</exception>
public HostBuilder Configure(HostBuilder builder)
{
if (builder == null)
Expand All @@ -52,49 +63,91 @@ public HostBuilder Configure(HostBuilder builder)
return builder;
}

/// <summary>
/// Adds a restart service recovery action with the specified delay.
/// </summary>
/// <param name="delay">The delay.</param>
/// <returns>The service recovery configurator.</returns>
public ServiceRecoveryConfigurator RestartService(TimeSpan delay)
{
Options.AddAction(new RestartServiceRecoveryAction(delay));

return this;
}

/// <summary>
/// Adds a restart service recovery action with the specified delay in minutes.
/// </summary>
/// <param name="delayInMinutes">The delay in minutes.</param>
/// <returns>The service recovery configurator.</returns>
public ServiceRecoveryConfigurator RestartService(int delayInMinutes)
{
return RestartService(TimeSpan.FromMinutes(delayInMinutes));
}

/// <summary>
/// Adds a restart computer recovery action with the specified delay.
/// </summary>
/// <param name="delay">The delay.</param>
/// <param name="message">The message.</param>
/// <returns>ServiceRecoveryConfigurator.</returns>
public ServiceRecoveryConfigurator RestartComputer(TimeSpan delay, string message)
{
Options.AddAction(new RestartSystemRecoveryAction(delay, message));

return this;
}

/// <summary>
/// Adds a restart computer recovery action with the specified delay in minutes.
/// </summary>
/// <param name="delayInMinutes">The delay in minutes.</param>
/// <param name="message">The message.</param>
/// <returns>The service recovery configurator.</returns>
public ServiceRecoveryConfigurator RestartComputer(int delayInMinutes, string message)
{
return RestartComputer(TimeSpan.FromMinutes(delayInMinutes), message);
}

/// <summary>
/// Adds a run program recovery action with the specified delay.
/// </summary>
/// <param name="delay">The delay.</param>
/// <param name="command">The command to run.</param>
/// <returns>The service recovery configurator.</returns>
public ServiceRecoveryConfigurator RunProgram(TimeSpan delay, string command)
{
Options.AddAction(new RunProgramRecoveryAction(delay, command));

return this;
}

/// <summary>
/// Adds a run program recovery action with the specified delay in minutes.
/// </summary>
/// <param name="delayInMinutes">The delay in minutes.</param>
/// <param name="command">The command.</param>
/// <returns>The service recovery configurator.</returns>
public ServiceRecoveryConfigurator RunProgram(int delayInMinutes, string command)
{
return RunProgram(TimeSpan.FromMinutes(delayInMinutes), command);
}

/// <summary>
/// Sets the recovery reset period in days.
/// </summary>
/// <param name="days">The reset period in days.</param>
public ServiceRecoveryConfigurator SetResetPeriod(int days)
{
Options.ResetPeriod = days;

return this;
}

/// <summary>
/// Specifies that the recovery actions should only be taken on a service crash. If the service exits
/// with a non-zero exit code, it will not be restarted.
/// </summary>
public void OnCrashOnly()
{
Options.RecoverOnCrashOnly = true;
Expand Down
6 changes: 3 additions & 3 deletions src/Topshelf/Configuration/Options/ServiceRecoveryOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -47,13 +47,13 @@ public void ApplyTo(HostConfigurator configurator)
switch (option)
{
case RestartServiceRecoveryAction restartServiceRecoveryAction:
recoveryHostConfigurator.RestartService(restartServiceRecoveryAction.Delay);
recoveryHostConfigurator.RestartService(restartServiceRecoveryAction.Delay / 60000);
break;
case RestartSystemRecoveryAction restartSystemRecoveryAction:
recoveryHostConfigurator.RestartComputer(restartSystemRecoveryAction.Delay, restartSystemRecoveryAction.RestartMessage);
recoveryHostConfigurator.RestartComputer(restartSystemRecoveryAction.Delay / 60000, restartSystemRecoveryAction.RestartMessage);
break;
case RunProgramRecoveryAction runProgramRecoveryAction:
recoveryHostConfigurator.RunProgram(runProgramRecoveryAction.Delay, runProgramRecoveryAction.Command);
recoveryHostConfigurator.RunProgram(runProgramRecoveryAction.Delay / 60000, runProgramRecoveryAction.Command);
break;
}
}
Expand Down
27 changes: 18 additions & 9 deletions src/Topshelf/Configuration/ServiceRecoveryConfigurator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,52 +12,61 @@
// specific language governing permissions and limitations under the License.
namespace Topshelf
{
/// <summary>
/// Defines a service recovery configurator.
/// </summary>
public interface ServiceRecoveryConfigurator
{
/// <summary>
/// Restart the service after waiting the delay period specified
/// </summary>
/// <param name="delay"></param>
/// <param name="delay">The delay.</param>
/// <returns>The service recovery configurator.</returns>
ServiceRecoveryConfigurator RestartService(System.TimeSpan delay);

/// <summary>
/// Restart the service after waiting the delay period in minutes
/// </summary>
/// <param name="delayInMinutes"> </param>
/// <param name="delayInMinutes">The delay in minutes.</param>
/// <returns>The service recovery configurator.</returns>
ServiceRecoveryConfigurator RestartService(int delayInMinutes);

/// <summary>
/// Restart the computer after waiting the delay period specified
/// </summary>
/// <param name="delay"></param>
/// <param name="delay">The delay.</param>
/// <param name="message"></param>
/// <returns>The service recovery configurator.</returns>
ServiceRecoveryConfigurator RestartComputer(System.TimeSpan delay, string message);

/// <summary>
/// Restart the computer after waiting the delay period in minutes
/// </summary>
/// <param name="delayInMinutes"> </param>
/// <param name="delayInMinutes">The delay in minutes.</param>
/// <param name="message"> </param>
/// <returns>The service recovery configurator.</returns>
ServiceRecoveryConfigurator RestartComputer(int delayInMinutes, string message);

/// <summary>
/// Run the command specified
/// </summary>
/// <param name="delay"></param>
/// <param name="command"> </param>
/// <param name="delay">The delay.</param>
/// <param name="command">The command to run.</param>
/// <returns>The service recovery configurator.</returns>
ServiceRecoveryConfigurator RunProgram(System.TimeSpan delay, string command);

/// <summary>
/// Run the command specified
/// </summary>
/// <param name="delayInMinutes"> </param>
/// <param name="command"> </param>
/// <param name="delayInMinutes">The delay in minutes.</param>
/// <param name="command">The command to run.</param>
/// <returns>The service recovery configurator.</returns>
ServiceRecoveryConfigurator RunProgram(int delayInMinutes, string command);

/// <summary>
/// Specifies the reset period for the restart options
/// </summary>
/// <param name="days"> </param>
/// <param name="days">The reset period in days.</param>
ServiceRecoveryConfigurator SetResetPeriod(int days);

/// <summary>
Expand Down
7 changes: 7 additions & 0 deletions src/Topshelf/Runtime/Windows/NativeMethods.cs
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,14 @@ public enum SC_ACTION_TYPE
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public struct SC_ACTION
{
/// <summary>
/// The action to be performed. This member can be one of the following values from the <see cref="SC_ACTION_TYPE" /> enumeration type.
/// </summary>
public int Type;

/// <summary>
/// The time to wait before performing the specified action, in milliseconds.
/// </summary>
public int Delay;
}

Expand Down
20 changes: 16 additions & 4 deletions src/Topshelf/Runtime/Windows/RestartServiceRecoveryAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,33 @@
// specific language governing permissions and limitations under the License.
namespace Topshelf.Runtime.Windows
{
/// <summary>
/// Represents a restart service service recovery action.
/// </summary>
/// <seealso cref="Topshelf.Runtime.Windows.ServiceRecoveryAction" />
public class RestartServiceRecoveryAction :
ServiceRecoveryAction
{
/// <summary>
/// Initializes a new instance of the <see cref="RestartServiceRecoveryAction"/> class.
/// </summary>
/// <param name="delay">The delay.</param>
public RestartServiceRecoveryAction(System.TimeSpan delay)
: base(delay)
{
}

/// <summary>
/// Gets the service recovery configuration action.
/// </summary>
/// <returns>A <see cref="NativeMethods.SC_ACTION"/> representing the restart service service recovery configuration action.</returns>
public override NativeMethods.SC_ACTION GetAction()
{
return new NativeMethods.SC_ACTION
{
Delay = Delay,
Type = (int)NativeMethods.SC_ACTION_TYPE.RestartService,
};
{
Delay = Delay,
Type = (int)NativeMethods.SC_ACTION_TYPE.RestartService,
};
}
}
}
25 changes: 21 additions & 4 deletions src/Topshelf/Runtime/Windows/RestartSystemRecoveryAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,41 @@
// specific language governing permissions and limitations under the License.
namespace Topshelf.Runtime.Windows
{
/// <summary>
/// Represents a restart system service recovery action.
/// </summary>
/// <seealso cref="Topshelf.Runtime.Windows.ServiceRecoveryAction" />
public class RestartSystemRecoveryAction :
ServiceRecoveryAction
{
/// <summary>
/// Initializes a new instance of the <see cref="RestartSystemRecoveryAction"/> class.
/// </summary>
/// <param name="delay">The delay.</param>
/// <param name="restartMessage">The restart message.</param>
public RestartSystemRecoveryAction(System.TimeSpan delay, string restartMessage)
: base(delay)
{
RestartMessage = restartMessage;
}

/// <summary>
/// Gets the system restart message.
/// </summary>
/// <value>The system restart message.</value>
public string RestartMessage { get; private set; }

/// <summary>
/// Gets the service recovery configuration action.
/// </summary>
/// <returns>A <see cref="NativeMethods.SC_ACTION"/> representing the restart system service recovery configuration action.</returns>
public override NativeMethods.SC_ACTION GetAction()
{
return new NativeMethods.SC_ACTION
{
Delay = Delay,
Type = (int)NativeMethods.SC_ACTION_TYPE.RebootComputer,
};
{
Delay = Delay,
Type = (int)NativeMethods.SC_ACTION_TYPE.RebootComputer,
};
}
}
}
25 changes: 21 additions & 4 deletions src/Topshelf/Runtime/Windows/RunProgramRecoveryAction.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,41 @@
// specific language governing permissions and limitations under the License.
namespace Topshelf.Runtime.Windows
{
/// <summary>
/// Represents a run command service recovery action.
/// </summary>
/// <seealso cref="Topshelf.Runtime.Windows.ServiceRecoveryAction" />
public class RunProgramRecoveryAction :
ServiceRecoveryAction
{
/// <summary>
/// Initializes a new instance of the <see cref="RunProgramRecoveryAction"/> class.
/// </summary>
/// <param name="delay">The delay.</param>
/// <param name="command">The command.</param>
public RunProgramRecoveryAction(System.TimeSpan delay, string command)
: base(delay)
{
Command = command;
}

/// <summary>
/// Gets the command to run.
/// </summary>
/// <value>The command. to run</value>
public string Command { get; private set; }

/// <summary>
/// Gets the service recovery configuration action.
/// </summary>
/// <returns>A <see cref="NativeMethods.SC_ACTION"/> representing the run command service recovery configuration action.</returns>
public override NativeMethods.SC_ACTION GetAction()
{
return new NativeMethods.SC_ACTION
{
Delay = Delay,
Type = (int)NativeMethods.SC_ACTION_TYPE.RunCommand,
};
{
Delay = Delay,
Type = (int)NativeMethods.SC_ACTION_TYPE.RunCommand,
};
}
}
}
Loading

0 comments on commit 5a22972

Please sign in to comment.