Skip to content

Commit

Permalink
Adds run history to the UI
Browse files Browse the repository at this point in the history
Fixes an issue with wcf channels timing out
Fixes an issue where the notes field did not save
  • Loading branch information
ryannewington committed Aug 20, 2017
1 parent 221de54 commit 013306b
Show file tree
Hide file tree
Showing 29 changed files with 663 additions and 271 deletions.
Binary file not shown.
5 changes: 2 additions & 3 deletions src/Lithnet.Miiserver.AutoSync/Config/RegistrySettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public static RegistryKey BaseKey
{
if (RegistrySettings.key == null)
{
RegistrySettings.key = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Services\\miisautosync\\Parameters", true);
RegistrySettings.key = Registry.LocalMachine.OpenSubKey("System\\CurrentControlSet\\Services\\miisautosync\\Parameters", false);
}

return RegistrySettings.key;
Expand All @@ -30,10 +30,9 @@ public static bool ExecutionEngineEnabled
{
get
{
int? value = RegistrySettings.BaseKey.GetValue("ExecutionEngineEnabled", 0) as int?;
int? value = RegistrySettings.BaseKey.GetValue("ExecutionEngineEnabled", 1) as int?;
return value.HasValue && value.Value != 0;
}
set => RegistrySettings.BaseKey.SetValue("ExecutionEngineEnabled", value ? 1 : 0);
}

public static string LogPath
Expand Down
3 changes: 3 additions & 0 deletions src/Lithnet.Miiserver.AutoSync/ConfigService/ConfigClient.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text;
using System.ServiceModel;
using System.Runtime.Serialization;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;

namespace Lithnet.Miiserver.AutoSync
Expand Down Expand Up @@ -82,5 +83,7 @@ public void RestartChangedExecutors()
{
this.Channel.RestartChangedExecutors();
}


}
}
7 changes: 7 additions & 0 deletions src/Lithnet.Miiserver.AutoSync/ConfigService/ConfigService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ public ConfigFile GetConfig()
try
{
Trace.WriteLine($"Calling {nameof(this.GetConfig)} as {Environment.UserName}");
Global.ThrowOnSyncEngineNotRunning();
ProtectedString.EncryptOnWrite = false;
return Program.ActiveConfig;
}
Expand Down Expand Up @@ -96,6 +97,7 @@ public void PutConfigAndReloadChanged(ConfigFile config)
try
{
Trace.WriteLine($"Calling {nameof(this.PutConfig)} as {Environment.UserName}");
Global.ThrowOnSyncEngineNotRunning();
ProtectedString.EncryptOnWrite = true;
ConfigFile.Save(config, RegistrySettings.ConfigurationFile);
Program.ActiveConfig = config;
Expand All @@ -113,6 +115,7 @@ public void Reload()
try
{
Trace.WriteLine($"Calling {nameof(this.Reload)} as {Environment.UserName}");
Global.ThrowOnSyncEngineNotRunning();
Program.Reload();
}
catch (Exception ex)
Expand Down Expand Up @@ -153,6 +156,7 @@ public void Start(string managementAgentName)
{
try
{
Global.ThrowOnSyncEngineNotRunning();
Program.StartExecutor(managementAgentName);
}
catch (Exception ex)
Expand All @@ -179,6 +183,7 @@ public void StartAll()
{
try
{
Global.ThrowOnSyncEngineNotRunning();
Program.StartExecutors();
}
catch (Exception ex)
Expand All @@ -195,6 +200,7 @@ public ExecutorState GetEngineState()

public IList<string> GetManagementAgentNames()
{
Global.ThrowOnSyncEngineNotRunning();
return ManagementAgent.GetManagementAgents().Select(t => t.Name).ToList();
}

Expand All @@ -205,6 +211,7 @@ public IList<string> GetManagementAgentsPendingRestart()

public void RestartChangedExecutors()
{
Global.ThrowOnSyncEngineNotRunning();
Program.RestartChangedExecutors();
}
}
Expand Down
107 changes: 96 additions & 11 deletions src/Lithnet.Miiserver.AutoSync/EventService/EventService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.ServiceModel;
using System.ServiceModel.Description;
using System.Text;
using System.Threading.Tasks;
using Lithnet.Logging;
using System.Diagnostics;

Expand Down Expand Up @@ -49,21 +47,51 @@ public static ServiceHost CreateInstance()
}
}

private static Dictionary<string, MAStateChangedEventHandler> eventHandlers;
private static ConcurrentDictionary<string, MAStateChangedEventHandler> statusChangedEventHandlers;

private static ConcurrentDictionary<string, RunProfileExecutionCompleteEventHandler> executionCompleteEventHandlers;

internal delegate void MAStateChangedEventHandler(MAStatus status);

internal static void NotifySubscribers(MAStatus status)
internal delegate void RunProfileExecutionCompleteEventHandler(string runProfileName, string runProfileResult);

internal static void NotifySubscribersOnStatusChange(MAStatus status)
{
if (EventService.statusChangedEventHandlers.ContainsKey(status.MAName))
{
try
{
EventService.statusChangedEventHandlers[status.MAName]?.Invoke(status);
}
catch (Exception ex)
{
Logger.WriteLine("Error notifying client");
Logger.WriteException(ex);
}
}
}

internal static void NotifySubscribersOnRunProfileExecutionComplete(string managementAgentName, string runProfileName, string runProfileResult)
{
if (EventService.eventHandlers.ContainsKey(status.MAName))
if (EventService.executionCompleteEventHandlers.ContainsKey(managementAgentName))
{
EventService.eventHandlers[status.MAName]?.Invoke(status);
try
{
EventService.executionCompleteEventHandlers[managementAgentName]?.Invoke(runProfileName, runProfileResult);
}
catch (Exception ex)
{
Logger.WriteLine("Error notifying client");
Logger.WriteException(ex);
}
}
}


static EventService()
{
EventService.eventHandlers = new Dictionary<string, MAStateChangedEventHandler>(StringComparer.OrdinalIgnoreCase);
EventService.statusChangedEventHandlers = new ConcurrentDictionary<string, MAStateChangedEventHandler>(StringComparer.OrdinalIgnoreCase);
EventService.executionCompleteEventHandlers = new ConcurrentDictionary<string, RunProfileExecutionCompleteEventHandler>(StringComparer.OrdinalIgnoreCase);
}

public void Register(string managementAgentName)
Expand All @@ -72,12 +100,32 @@ public void Register(string managementAgentName)
{
IEventCallBack subscriber = OperationContext.Current.GetCallbackChannel<IEventCallBack>();

if (!EventService.eventHandlers.ContainsKey(managementAgentName))
if (!EventService.statusChangedEventHandlers.ContainsKey(managementAgentName))
{
EventService.statusChangedEventHandlers.TryAdd(managementAgentName, null);
}

EventService.statusChangedEventHandlers[managementAgentName] += subscriber.MAStatusChanged;


if (!EventService.executionCompleteEventHandlers.ContainsKey(managementAgentName))
{
EventService.eventHandlers.Add(managementAgentName, null);
EventService.executionCompleteEventHandlers.TryAdd(managementAgentName, null);
}

EventService.eventHandlers[managementAgentName] += subscriber.MAStatusChanged;
EventService.executionCompleteEventHandlers[managementAgentName] += subscriber.RunProfileExecutionComplete;


// ReSharper disable once SuspiciousTypeConversion.Global
ICommunicationObject commObj = subscriber as ICommunicationObject;
if (commObj != null)
{
commObj.Faulted += this.CommObj_Faulted;
commObj.Closed += this.CommObj_Closed;
}

Trace.WriteLine($"Registered callback channel for {managementAgentName}");

}
catch (Exception ex)
{
Expand All @@ -87,6 +135,43 @@ public void Register(string managementAgentName)
}
}

private void CommObj_Closed(object sender, EventArgs e)
{
this.DeregisterCallbackChannel(sender);
Trace.WriteLine("Deregistered closed callback channel");
}

private void CommObj_Faulted(object sender, EventArgs e)
{
this.DeregisterCallbackChannel(sender);
Trace.WriteLine("Deregistered faulted callback channel");
}

private void DeregisterCallbackChannel(object sender)
{
IEventCallBack subscriber = sender as IEventCallBack;

if (subscriber != null)
{
foreach (string ma in EventService.statusChangedEventHandlers.Keys.ToArray())
{
EventService.statusChangedEventHandlers[ma] -= subscriber.MAStatusChanged;
}

foreach (string ma in EventService.executionCompleteEventHandlers.Keys.ToArray())
{
EventService.executionCompleteEventHandlers[ma] -= subscriber.RunProfileExecutionComplete;
}

// ReSharper disable once SuspiciousTypeConversion.Global
ICommunicationObject commObj = subscriber as ICommunicationObject;
if (commObj != null)
{
commObj.Closed -= this.CommObj_Closed;
}
}
}

public MAStatus GetFullUpdate(string managementAgentName)
{
try
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,16 +38,16 @@ public static Binding NetNamedPipeBinding
{
get
{
int timeout = System.Diagnostics.Debugger.IsAttached ? 900 : 100;
int timeout = System.Diagnostics.Debugger.IsAttached ? 60 : 60;

NetNamedPipeBinding binding = new NetNamedPipeBinding();
binding.MaxReceivedMessageSize = int.MaxValue;
binding.ReaderQuotas.MaxStringContentLength = int.MaxValue;
binding.ReaderQuotas.MaxBytesPerRead = int.MaxValue;
binding.CloseTimeout = TimeSpan.FromSeconds(timeout);
binding.OpenTimeout = TimeSpan.FromSeconds(timeout);
binding.ReceiveTimeout = TimeSpan.FromSeconds(timeout);
binding.SendTimeout = TimeSpan.FromSeconds(timeout);
binding.ReceiveTimeout = TimeSpan.MaxValue;
binding.SendTimeout = TimeSpan.MaxValue;
binding.TransactionFlow = false;
binding.Security.Mode = NetNamedPipeSecurityMode.Transport;
binding.Security.Transport.ProtectionLevel = System.Net.Security.ProtectionLevel.None;
Expand Down
3 changes: 3 additions & 0 deletions src/Lithnet.Miiserver.AutoSync/EventService/IEventCallback.cs
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,8 @@ public interface IEventCallBack
{
[OperationContract (IsOneWay = true)]
void MAStatusChanged(MAStatus status);

[OperationContract(IsOneWay = true)]
void RunProfileExecutionComplete(string runProfileName, string result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
using System;

namespace Lithnet.Miiserver.AutoSync
{
[Serializable]
public class SyncEngineStoppedException : Exception
{
public SyncEngineStoppedException()
{
}

public SyncEngineStoppedException(string message)
: base(message)
{
}

public SyncEngineStoppedException(string message, Exception innerException)
: base(message, innerException)
{
}
}
}
71 changes: 40 additions & 31 deletions src/Lithnet.Miiserver.AutoSync/ExecutionEngine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,17 @@ public IList<string> GetManagementAgentsPendingRestart()
continue;
}

if (e.Configuration == null || e.Configuration.Version != newItem.Version)
if (e.ControlState == ControlState.Stopped)
{
continue;
}

if (e.Configuration == null)
{
continue;
}

if (e.Configuration.Version != newItem.Version)
{
restartItems.Add(newItem.ManagementAgentName);
}
Expand Down Expand Up @@ -172,51 +182,50 @@ private void InitializeMAExecutors()
{
MAExecutor x = new MAExecutor(ma);
x.StateChanged += this.X_StateChanged;
x.RunProfileExecutionComplete += this.X_RunProfileExecutionComplete;
this.maExecutors.Add(ma.Name, x);
}
}

private void X_RunProfileExecutionComplete(object sender, string runProfileName, string result)
{
EventService.NotifySubscribersOnRunProfileExecutionComplete(((MAExecutor)sender).ManagementAgentName, runProfileName, result);
}

private void X_StateChanged(object sender, MAStatusChangedEventArgs e)
{
EventService.NotifySubscribersOnStatusChange(e.Status);
}

private void StartMAExecutors()
{
this.cancellationToken = new CancellationTokenSource();

if (RegistrySettings.ExecutionEngineEnabled)
foreach (MAConfigParameters c in Program.ActiveConfig.ManagementAgents)
{
foreach (MAConfigParameters c in Program.ActiveConfig.ManagementAgents)
if (c.IsMissing)
{
if (c.IsMissing)
{
Logger.WriteLine("{0}: Skipping management agent because it is missing from the Sync Engine", c.ManagementAgentName);
continue;
}
Logger.WriteLine("{0}: Skipping management agent because it is missing from the Sync Engine", c.ManagementAgentName);
continue;
}

if (this.maExecutors.ContainsKey(c.ManagementAgentName))
if (this.maExecutors.ContainsKey(c.ManagementAgentName))
{
Trace.WriteLine($"Starting {c.ManagementAgentName}");
Task.Run(() =>
{
Trace.WriteLine($"Starting {c.ManagementAgentName}");
Task.Run(() =>
MAExecutor e = this.maExecutors[c.ManagementAgentName];
lock (e)
{
MAExecutor e = this.maExecutors[c.ManagementAgentName];
lock (e)
{
e.Start(c);
}
}, this.cancellationToken.Token);
}
else
{
Logger.WriteLine($"Cannot start management agent executor '{c.ManagementAgentName}' because the management agent was not found");
}
e.Start(c);
}
}, this.cancellationToken.Token);
}
else
{
Logger.WriteLine($"Cannot start management agent executor '{c.ManagementAgentName}' because the management agent was not found");
}
}
else
{
Logger.WriteLine("Execution engine has been disabled");
}
}

private void X_StateChanged(object sender, MAStatusChangedEventArgs e)
{
EventService.NotifySubscribers(e.Status);
}

private void StopMAExecutors()
Expand Down
Loading

0 comments on commit 013306b

Please sign in to comment.