Skip to content

Commit

Permalink
Server disposing refactoring, added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lilla28 committed Apr 4, 2023
1 parent e5695dd commit 0b7b8b8
Show file tree
Hide file tree
Showing 22 changed files with 618 additions and 595 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,28 +40,34 @@ public void UpdateConnection(ConnectionInfo connection)
lock (_locker)
{
var index = Connections.IndexOf(connection);
if (index == -1)
{
var element = Connections.FirstOrDefault(c => c.Id == connection.Id);
if(element != null)
index = Connections.IndexOf(element);
}
if (index >= 0)
{
Connections[index] = connection;
}
}
}

public void UpdateEnvironmentVariables(IEnumerable<KeyValuePair<string, string>> envs)
public void UpdateOrAddEnvironmentVariables(IEnumerable<KeyValuePair<string, string>> envs)
{
foreach (var item in envs)
{
EnvironmentVariables.AddOrUpdate(item.Key, item.Value, (_, _) => item.Value);
}
}

public void UpdateRegistrations(IEnumerable<RegistrationInfo> services)
public void UpdateOrAddRegistrations(IEnumerable<RegistrationInfo> services)
{
UpdateOrAdd(services, Registrations, (item) => reg => reg.ImplementationType == item.ImplementationType &&
reg.ServiceType == item.ServiceType && reg.LifeTime == item.LifeTime);
}

public void UpdateModules(IEnumerable<ModuleInfo> currentModules)
public void UpdateOrAddModules(IEnumerable<ModuleInfo> currentModules)
{
UpdateOrAdd(currentModules, Modules, (item) => (item2) => item.Name == item2.Name && item.PublicKeyToken == item2.PublicKeyToken);
}
Expand Down Expand Up @@ -90,6 +96,10 @@ private void UpdateOrAdd<T>(IEnumerable<T> source, SynchronizedCollection<T> tar
target.Add(item);
}
}
else
{
target.Add(item);
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,14 @@ public interface IProcessInfoAggregator : IDisposable
public int MainProcessId { get; }

/// <summary>
/// Adds a runtime information to the collection.
/// Delay for actually sending terminate request for the UI.
/// </summary>
/// <param name="assemblyId"></param>
/// <param name="processInfo"></param>
Task AddRuntimeInformation(string assemblyId, ProcessInfoCollectorData processInfo);
public int TerminatingProcessDelay { get; }

/// <summary>
/// Controls the initialized subsystems.
/// </summary>
public ISubsystemController? SubsystemController { get; }

/// <summary>
/// Removes a module information from the collection.
Expand Down Expand Up @@ -71,41 +74,6 @@ public interface IProcessInfoAggregator : IDisposable
/// <param name="handler"></param>
void RemoveUiConnection(KeyValuePair<Guid, IUIHandler> handler);

/// <summary>
/// Adds or updates the connections in the collection.
/// </summary>
/// <param name="assemblyId"></param>
/// <param name="connections"></param>
Task AddConnectionCollection(string assemblyId, IEnumerable<ConnectionInfo> connections);

/// <summary>
/// Updates a connection.
/// </summary>
/// <param name="assemblyId"></param>
/// <param name="connectionInfo"></param>
Task UpdateConnectionInfo(string assemblyId, ConnectionInfo connectionInfo);

/// <summary>
/// Updates the environment variables.
/// </summary>
/// <param name="assemblyId"></param>
/// <param name="environmentVariables"></param>
Task UpdateEnvironmentVariablesInfo(string assemblyId, IEnumerable<KeyValuePair<string, string>> environmentVariables);

/// <summary>
/// Updates the registrations in the collection.
/// </summary>
/// <param name="assemblyId"></param>
/// <param name="registrations"></param>
Task UpdateRegistrationInfo(string assemblyId, IEnumerable<RegistrationInfo> registrations);

/// <summary>
/// Updates the modules in the collection.
/// </summary>
/// <param name="assemblyId"></param>
/// <param name="modules"></param>
Task UpdateModuleInfo(string assemblyId, IEnumerable<ModuleInfo> modules);

/// <summary>
/// Enables to watch processes through ProcessMonitor.
/// Only available for Windows OS.
Expand All @@ -124,62 +92,72 @@ public interface IProcessInfoAggregator : IDisposable
void InitProcesses(ReadOnlySpan<int> processIds);

/// <summary>
/// Initializes the subsystems taken from the user defined manifest.
/// Puts the given subsystem into the queue to send subsystem state changed information to the UI's.
/// </summary>
/// <param name="subsystems"></param>
/// <returns></returns>
Task InitializeSubsystems(IEnumerable<KeyValuePair<Guid, SubsystemInfo>> subsystems);
/// <param name="instanceId"></param>
/// <param name="state"></param>
void ScheduleSubsystemStateChanged(Guid instanceId, string state);

/// <summary>
/// Terminates the given subsystems through the user defined ISubsystemLauncher.
/// Returns the initialized runtime information.
/// </summary>
/// <param name="subsystemIds"></param>
/// <returns></returns>
Task ShutdownSubsystems(IEnumerable<string> subsystemIds);
IEnumerable<KeyValuePair<string, ProcessInfoCollectorData>> GetRuntimeInformation();

/// <summary>
/// Restarts the given subsystems through the user defined ISubsystemLauncher.
/// Returns the connected clients.
/// </summary>
/// <param name="subsystemIds"></param>
/// <returns></returns>
Task RestartSubsystems(IEnumerable<string> subsystemIds);
IEnumerable<KeyValuePair<Guid, IUIHandler>> GetUiClients();

/// <summary>
/// Launch the given subsystems through the user defined ISubsystemLauncher.
/// Adds a runtime information to the collection.
/// </summary>
/// <param name="subsystemIds"></param>
/// <returns></returns>
Task LaunchSubsystems(IEnumerable<string> subsystemIds);
/// <param name="assemblyId"></param>
/// <param name="processInfo"></param>
Task AddRuntimeInformation(string assemblyId, ProcessInfoCollectorData processInfo);

/// <summary>
/// Launch the given subsystem through the user defined ISubsystemLauncher and <paramref name="periodOfTime"/>.
/// Adds or updates the connections in the collection.
/// </summary>
/// <param name="id"></param>
/// <param name="periodOfTime"></param>
/// <returns></returns>
Task LaunchSubsystemWithDelay(Guid id, int periodOfTime);
/// <param name="assemblyId"></param>
/// <param name="connections"></param>
Task AddConnectionCollection(string assemblyId, IEnumerable<ConnectionInfo> connections);

/// <summary>
/// Modifies a state of a subsystem with the given data. Send update to the registered UIs.
/// Updates a connection.
/// </summary>
/// <param name="subsystemId"></param>
/// <param name="state"></param>
/// <returns></returns>
Task ModifySubsystemState(Guid subsystemId, string state);
/// <param name="assemblyId"></param>
/// <param name="connectionInfo"></param>
Task UpdateOrAddConnectionInfo(string assemblyId, ConnectionInfo connectionInfo);

/// <summary>
/// Adds processes to watch to the existing watchable process ids list.
/// Updates the environment variables.
/// </summary>
/// <param name="processIds"></param>
/// <returns></returns>
ValueTask AddProcesses(ReadOnlySpan<int> processIds);
/// <param name="assemblyId"></param>
/// <param name="environmentVariables"></param>
Task UpdateOrAddEnvironmentVariablesInfo(string assemblyId, IEnumerable<KeyValuePair<string, string>> environmentVariables);

/// <summary>
/// Puts the given subsystem into the queue to send subsystem state changed information to the UI's.
/// Adds the registrations to the collection.
/// </summary>
/// <param name="instanceId"></param>
/// <param name="state"></param>
void ScheduleSubsystemStateChanged(Guid instanceId, string state);
/// <param name="assemblyId"></param>
/// <param name="registrations"></param>
Task UpdateRegistrations(string assemblyId, IEnumerable<RegistrationInfo> registrations);

/// <summary>
/// Updates the modules to the collection.
/// </summary>
/// <param name="assemblyId"></param>
/// <param name="modules"></param>
Task UpdateOrAddModuleInfo(string assemblyId, IEnumerable<ModuleInfo> modules);

/// <summary>
/// Adds processes to watch to the existing watchable process ids list.
/// </summary>
/// <param name="processIds"></param>
/// <returns></returns>
Task AddProcesses(ReadOnlySpan<int> processIds);

/// <summary>
/// Asynchronusly dequeue the changes of the registered subsystems, and send to the initialized UI's.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
// Morgan Stanley makes this available to you under the Apache License,
// Version 2.0 (the "License"). You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0.
//
// See the NOTICE file distributed with this work for additional information
// regarding copyright ownership. Unless required by applicable law or agreed
// to in writing, software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
// or implied. See the License for the specific language governing permissions
// and limitations under the License.

using ProcessExplorer.Abstractions.Handlers;

namespace ProcessExplorer.Abstractions.Processes;

//TODO(Lilla): Add description
public interface IProcessInfoManager : IDisposable
{
ReadOnlySpan<int> AddChildProcesses(int processId, string? processName);
void AddProcess(int processId);
bool CheckIfIsComposeProcess(int processId);
void ClearProcessIds();
bool ContainsId(int processId);
float GetCpuUsage(int processId, string processName);
float GetMemoryUsage(int processId, string processName);
int? GetParentId(int processId, string processName);
ReadOnlySpan<int> GetProcessIds();
void RemoveProcessId(int processId);
void SendNewProcessUpdate(int processId);
void SendProcessModifiedUpdate(int processId);
void SendTerminatedProcessUpdate(int processId);
void SetHandlers(
ProcessModifiedHandler processModifiedHandler,
ProcessTerminatedHandler processTerminatedHandler,
ProcessCreatedHandler processCreatedHandler,
ProcessesModifiedHandler processesModifiedHandler,
ProcessStatusChangedHandler processStatusChangedHandler);
void SetProcessIds(int mainProcessId, ReadOnlySpan<int> processIds);
void WatchProcesses(int mainProcessId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

namespace ProcessExplorer.Abstractions.Processes;

public abstract class ProcessInfoManager : IDisposable //Create an interface
public abstract class ProcessInfoManager : IProcessInfoManager
{
private ProcessCreatedHandler? _processCreatedHandler;
private ProcessModifiedHandler? _processModifiedHandler;
Expand All @@ -30,16 +30,13 @@ public abstract class ProcessInfoManager : IDisposable //Create an interface
private readonly ILogger _logger;
private readonly ObservableCollection<int> _processIds = new();
private readonly object _locker = new();
private int _composePid;
private int _delayTime;

public ProcessInfoManager(ILogger? logger)
{
_logger = logger ?? NullLogger.Instance;
_processIds.CollectionChanged += ProcessIdsChanged;
}


private void ProcessIdsChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
Expand Down Expand Up @@ -78,11 +75,6 @@ public void SetHandlers(
_processesModifiedHandler = processesModifiedHandler;
}

public void SetComposePid(int processId)
{
_composePid = processId;
}

public bool ContainsId(int processId)
{
lock (_locker)
Expand All @@ -109,7 +101,9 @@ public void RemoveProcessId(int processId)
}
}

public void SetProcessIds(ReadOnlySpan<int> processIds)
public void SetProcessIds(
int mainProcessId,
ReadOnlySpan<int> processIds)
{
lock (_locker)
{
Expand All @@ -120,7 +114,8 @@ public void SetProcessIds(ReadOnlySpan<int> processIds)
AddChildProcesses(id, Process.GetProcessById(id).ProcessName);
}

if(_composePid != 0 && !_processIds.Contains(_composePid)) _processIds.Add(_composePid);
if (mainProcessId != 0 && !_processIds.Contains(mainProcessId))
_processIds.Add(mainProcessId);
}
}

Expand Down Expand Up @@ -162,11 +157,11 @@ public void ClearProcessIds()
/// <summary>
/// Continuously watching created processes.
/// </summary>
public virtual void WatchProcesses()
public virtual void WatchProcesses(int mainProcessId)
{
if(_composePid == 0) return;
AddProcess(_composePid);
AddChildProcesses(_composePid, Process.GetProcessById(_composePid).ProcessName);
if (mainProcessId == 0) return;
AddProcess(mainProcessId);
AddChildProcesses(mainProcessId, Process.GetProcessById(mainProcessId).ProcessName);
}

/// <summary>
Expand All @@ -179,7 +174,7 @@ private bool IsComposeProcess(int processId)
//snapshot if the process has already exited
if (!Process.GetProcesses().Any(p => p.Id == processId)) return false;

if (processId == _composePid || ContainsId(processId)) return true;
if (ContainsId(processId)) return true;

var parentProcessId = GetParentId(processId, Process.GetProcessById(processId).ProcessName);

Expand Down Expand Up @@ -229,11 +224,6 @@ public void SendProcessModifiedUpdate(int processId)
_processModifiedHandler?.Invoke(processId);
}

public void SetDeadProcessRemovalDelay(int delay)
{
_delayTime = delay * 100;
}

~ProcessInfoManager()
{
Dispose();
Expand Down Expand Up @@ -270,14 +260,10 @@ private bool TryDeleteProcess(int processId)
return false;
}

private async void RemoveProcessAfterTimeout(int processId)
private void RemoveProcessAfterTimeout(int processId)
{
await Task.Run(() =>
{
Task.Delay(_delayTime);
var ids = GetProcessIds();
_processesModifiedHandler?.Invoke(ids);
_processTerminatedHandler?.Invoke(processId);
});
var ids = GetProcessIds();
_processesModifiedHandler?.Invoke(ids);
_processTerminatedHandler?.Invoke(processId);
}
}

This file was deleted.

Loading

0 comments on commit 0b7b8b8

Please sign in to comment.