Skip to content
This repository has been archived by the owner on Sep 3, 2024. It is now read-only.

Feat server #63

Merged
merged 5 commits into from
Dec 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions EasyLib/Api/JobManagerClient.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace EasyLib.Api;

public class JobManagerClient
{
}
126 changes: 126 additions & 0 deletions EasyLib/Api/JobManagerServer.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
using System.Net;
using System.Net.Sockets;
using EasyLib.Enums;
using EasyLib.Files;
using EasyLib.JobManager;
using EasyLib.Json;

namespace EasyLib.Api;

public class JobManagerServer
{
private readonly LocalJobManager _localJobManager;
private readonly TcpListener _serverSocket = null!;
private readonly List<Worker> _workers = new List<Worker>();
public readonly object ServerLockObject = new object();

public JobManagerServer(LocalJobManager localJobManager)
{
_localJobManager = localJobManager;
var serverPort = ConfigManager.Instance.ServerPort;
if (serverPort != null)
{
_serverSocket = new TcpListener(IPAddress.Any, serverPort.Value);
_serverSocket.Start();
new Thread(_waitForConnection).Start();
}
}

public CancellationTokenSource CancellationTokenSource { get; } = new CancellationTokenSource();

private void _waitForConnection()
{
try
{
while (true)
{
TcpClient socket = _serverSocket.AcceptTcpClient();

Worker worker = new Worker(socket, this);
AddWorker(worker);
worker.SendAllJobs(_localJobManager.GetJobs());
if (CancellationTokenSource.IsCancellationRequested)
break;
}
}
catch (SocketException e)

Check warning on line 46 in EasyLib/Api/JobManagerServer.cs

View workflow job for this annotation

GitHub Actions / Tests

The variable 'e' is declared but never used

Check warning on line 46 in EasyLib/Api/JobManagerServer.cs

View workflow job for this annotation

GitHub Actions / Tests

The variable 'e' is declared but never used
{
CleanInstance();
}
}

private void AddWorker(Worker worker)
{
lock (ServerLockObject)
{
_workers.Add(worker);
worker.Start();
}
}

public void RemoveWorker(Worker worker)
{
lock (ServerLockObject)
{
_workers.Remove(worker);
worker.Close();
}
}

public void Broadcast(ApiAction action, JsonJob jsonJob)
{
lock (ServerLockObject)
{
foreach (Worker worker in _workers)
{
worker.Send(new JsonApiRequest() { Action = action, Job = jsonJob });
}
}
}

public void ExecuteJobCommand(ApiAction action, Job.Job job)
{
var localJob = _localJobManager.GetJobsFromIds(new[] { (int)job.Id });
if (localJob.Count != 1)
return;
switch (action)
{
case ApiAction.Start:
_localJobManager.ExecuteJob(localJob[0]);
break;
case ApiAction.Cancel:
_localJobManager.CancelJob(localJob[0]);
break;
case ApiAction.Pause:
_localJobManager.PauseJob(localJob[0]);
break;
case ApiAction.Edit:
_localJobManager.EditJob(localJob[0], job.Name, job.SourceFolder, job.DestinationFolder, job.Type);
break;
case ApiAction.Delete:
_localJobManager.DeleteJob(localJob[0]);
break;
case ApiAction.Resume:
_localJobManager.ResumeJob(localJob[0]);
break;
case ApiAction.Create:
_localJobManager.CreateJob(job.Name, job.SourceFolder, job.DestinationFolder, job.Type);
break;
}
}

public void CleanInstance()
{
var numWorkers = _workers.Count;
for (var i = 0; i < numWorkers; i++)
{
lock (ServerLockObject)
{
_workers[i].Close();
}
}

_workers.Clear();
_serverSocket.Stop();
}
}
74 changes: 74 additions & 0 deletions EasyLib/Api/JobManagerServerWorker.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System.Net.Sockets;
using System.Text;
using EasyLib.Enums;
using EasyLib.Job;
using EasyLib.Json;

namespace EasyLib.Api;

public class Worker
{
private readonly JobManagerServer _server;
private readonly TcpClient _socket;
private readonly Stream _stream;

public Worker(TcpClient socket, JobManagerServer server)
{
this._socket = socket;
this._stream = socket.GetStream();
this._server = server;
}

public void Start()
{
new Thread(Run).Start();
}

public void Send(JsonApiRequest request)
{
string json = Newtonsoft.Json.JsonConvert.SerializeObject(request);
byte[] buffer = Encoding.UTF8.GetBytes(json);
_stream.Write(buffer, 0, buffer.Length);
}

private void Run()
{
try
{
byte[] buffer = new byte[2018];
while (true)
{
int receivedBytes = _stream.Read(buffer, 0, buffer.Length);
if (receivedBytes < 1)
break;
JsonApiRequest request =
Newtonsoft.Json.JsonConvert.DeserializeObject<JsonApiRequest>(
Encoding.UTF8.GetString(buffer, 0, receivedBytes));
_server.ExecuteJobCommand(request.Action, new LocalJob(request.Job));
if (_server.CancellationTokenSource.IsCancellationRequested)
break;
}
}
catch (Exception e)

Check warning on line 52 in EasyLib/Api/JobManagerServerWorker.cs

View workflow job for this annotation

GitHub Actions / Tests

The variable 'e' is declared but never used

Check warning on line 52 in EasyLib/Api/JobManagerServerWorker.cs

View workflow job for this annotation

GitHub Actions / Tests

The variable 'e' is declared but never used
{
Close();
lock (_server.ServerLockObject)
{
_server.RemoveWorker(this);
}
}
}

public void SendAllJobs(List<Job.Job> jobs)
{
foreach (Job.Job job in jobs)
{
Send(new JsonApiRequest() { Action = ApiAction.Create, Job = job.ToJsonJob() });
}
}

public void Close()
{
_stream.Close();
}
}
15 changes: 15 additions & 0 deletions EasyLib/Enums/ApiAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace EasyLib.Enums;

public enum ApiAction
{
Start,
Pause,
Resume,
Cancel,
Delete,
Edit,
Error,
State,
Progress,
Create,
}
7 changes: 4 additions & 3 deletions EasyLib/Events/ProcessStartEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -96,16 +96,17 @@ private void _checkProcesses(string processName)
{
while (true)
{
if (Process.GetProcessesByName(processName).Length > Interlocked.Read(ref _numberOfRunningProcesses))
var processesLength = Process.GetProcessesByName(processName).Length;
if (processesLength > Interlocked.Read(ref _numberOfRunningProcesses))
{
ProcessStarted();
}
else if (Process.GetProcessesByName(processName).Length < Interlocked.Read(ref _numberOfRunningProcesses))
else if (processesLength < Interlocked.Read(ref _numberOfRunningProcesses))
{
ProcessStopped();
}

Thread.Sleep(100);
Thread.Sleep(500);
if (_cancellationTokenSource.IsCancellationRequested) return;
}
}
Expand Down
4 changes: 2 additions & 2 deletions EasyLib/Files/References/ConfigManagerReference.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@
public string? EasyCryptoPath { get; set; }
public string? CompanySoftwareProcessPath { get; set; }
public ulong MaxFileSize { get; set; } = 1000000;
public int ServerPort { get; set; } = 4242;
public string ServerIp { get; set; } = "";
public int? ServerPort { get; set; } = null;
public string? ServerIp { get; set; } = null;

private static string GenerateRandomKey()
{
Expand Down Expand Up @@ -89,7 +89,7 @@
CompanySoftwareProcessPath = jsonConfig.CompanySoftwareProcessPath;
Language = CultureInfo.GetCultureInfo(jsonConfig.Language);
MaxFileSize = jsonConfig.MaxFileSize;
PriorityFileExtensions = jsonConfig.PriorityFileExtensions;

Check warning on line 92 in EasyLib/Files/References/ConfigManagerReference.cs

View workflow job for this annotation

GitHub Actions / Tests

Possible null reference assignment.

Check warning on line 92 in EasyLib/Files/References/ConfigManagerReference.cs

View workflow job for this annotation

GitHub Actions / Tests

Possible null reference assignment.

// If the key was null, write the new key
if (xorKey == null)
Expand Down
5 changes: 5 additions & 0 deletions EasyLib/JobManager/JobManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,11 @@ public virtual bool ExecuteJobs(IEnumerable<Job.Job> jobs)
.Aggregate(true, (current, result) => current && result);
}

public virtual void ExecuteJob(Job.Job job)
{
job.Run();
}

/// <summary>
/// Create a new job
/// </summary>
Expand Down
17 changes: 17 additions & 0 deletions EasyLib/JobManager/LocalJobManager.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using EasyLib.Api;
using EasyLib.Enums;
using EasyLib.Events;
using EasyLib.Files;
Expand All @@ -15,6 +16,8 @@
/// </summary>
private readonly bool _ramOnly;

private readonly JobManagerServer? _server;

/// <summary>
/// Event for when jobs need to wait for the company software to close
/// </summary>
Expand All @@ -28,7 +31,11 @@
FetchJobs();
}

_pauseJobEvent = new ProcessStartEvent(ConfigManager.Instance.CompanySoftwareProcessPath, this);

Check warning on line 34 in EasyLib/JobManager/LocalJobManager.cs

View workflow job for this annotation

GitHub Actions / Tests

Possible null reference argument for parameter 'processName' in 'ProcessStartEvent.ProcessStartEvent(string processName, JobManager jobManager)'.

Check warning on line 34 in EasyLib/JobManager/LocalJobManager.cs

View workflow job for this annotation

GitHub Actions / Tests

Possible null reference argument for parameter 'processName' in 'ProcessStartEvent.ProcessStartEvent(string processName, JobManager jobManager)'.
if (ConfigManager.Instance.ServerPort != null)
{
_server = new JobManagerServer(this);
}
}

public override void OnJobProgress(Job.Job job)
Expand All @@ -42,6 +49,11 @@
{
StateManager.Instance.WriteJobs(Jobs);
}

if (_server != null)
{
_server.Broadcast(ApiAction.Progress, job.ToJsonJob());
}
}

public override void OnJobStateChange(JobState state, Job.Job job)
Expand All @@ -57,6 +69,11 @@
public override void CleanStop()
{
_pauseJobEvent.Stop();
if (_server != null)
{
_server.CancellationTokenSource.Cancel();
_server.CleanInstance();
}
}

public override List<Job.Job> GetJobs()
Expand Down Expand Up @@ -234,6 +251,6 @@
public override void ReloadConfig()
{
_pauseJobEvent.Stop();
_pauseJobEvent = new ProcessStartEvent(ConfigManager.Instance.CompanySoftwareProcessPath, this);

Check warning on line 254 in EasyLib/JobManager/LocalJobManager.cs

View workflow job for this annotation

GitHub Actions / Tests

Possible null reference argument for parameter 'processName' in 'ProcessStartEvent.ProcessStartEvent(string processName, JobManager jobManager)'.

Check warning on line 254 in EasyLib/JobManager/LocalJobManager.cs

View workflow job for this annotation

GitHub Actions / Tests

Possible null reference argument for parameter 'processName' in 'ProcessStartEvent.ProcessStartEvent(string processName, JobManager jobManager)'.
}
}
9 changes: 9 additions & 0 deletions EasyLib/Json/JsonApiRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using EasyLib.Enums;

namespace EasyLib.Json;

public struct JsonApiRequest
{
public ApiAction Action { get; set; }
public JsonJob Job { get; set; }
}