Files
runner/src/Runner.Common/JobNotification.cs
T

168 lines
5.6 KiB
C#
Raw Normal View History

2023-06-02 21:47:59 +02:00
using System;
2019-10-10 00:52:42 -04:00
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
namespace GitHub.Runner.Common
{
[ServiceLocator(Default = typeof(JobNotification))]
public interface IJobNotification : IRunnerService, IDisposable
{
2019-12-04 10:18:37 -05:00
void JobStarted(Guid jobId, string accessToken, Uri serverUrl);
2019-10-10 00:52:42 -04:00
Task JobCompleted(Guid jobId);
2019-12-04 10:18:37 -05:00
void StartClient(string monitorSocketAddress);
2019-10-10 00:52:42 -04:00
}
public sealed class JobNotification : RunnerService, IJobNotification
{
private Socket _monitorSocket;
private bool _isMonitorConfigured = false;
2019-12-04 10:18:37 -05:00
public void JobStarted(Guid jobId, string accessToken, Uri serverUrl)
2019-10-10 00:52:42 -04:00
{
Trace.Info("Entering JobStarted Notification");
StartMonitor(jobId, accessToken, serverUrl);
}
public async Task JobCompleted(Guid jobId)
{
Trace.Info("Entering JobCompleted Notification");
await EndMonitor();
}
2019-12-04 10:18:37 -05:00
public void StartClient(string monitorSocketAddress)
2019-10-10 00:52:42 -04:00
{
ConnectMonitor(monitorSocketAddress);
}
2023-06-02 21:47:59 +02:00
2019-10-10 00:52:42 -04:00
private void StartMonitor(Guid jobId, string accessToken, Uri serverUri)
{
2023-06-02 21:47:59 +02:00
if (String.IsNullOrEmpty(accessToken))
2019-10-10 00:52:42 -04:00
{
Trace.Info("No access token could be retrieved to start the monitor.");
return;
}
try
{
Trace.Info("Entering StartMonitor");
if (_isMonitorConfigured)
{
String message = $"Start {jobId.ToString()} {accessToken} {serverUri.ToString()} {System.Diagnostics.Process.GetCurrentProcess().Id}";
Trace.Info("Writing StartMonitor to socket");
_monitorSocket.Send(Encoding.UTF8.GetBytes(message));
Trace.Info("Finished StartMonitor writing to socket");
}
}
catch (SocketException e)
{
Trace.Error($"Failed sending StartMonitor message on socket!");
Trace.Error(e);
}
catch (Exception e)
{
Trace.Error($"Unexpected error occurred while sending StartMonitor message on socket!");
Trace.Error(e);
}
}
private async Task EndMonitor()
{
try
{
Trace.Info("Entering EndMonitor");
if (_isMonitorConfigured)
{
String message = $"End {System.Diagnostics.Process.GetCurrentProcess().Id}";
Trace.Info("Writing EndMonitor to socket");
_monitorSocket.Send(Encoding.UTF8.GetBytes(message));
Trace.Info("Finished EndMonitor writing to socket");
2023-06-02 21:47:59 +02:00
await Task.Delay(TimeSpan.FromSeconds(2));
2019-10-10 00:52:42 -04:00
}
}
catch (SocketException e)
{
Trace.Error($"Failed sending end message on socket!");
Trace.Error(e);
}
catch (Exception e)
{
Trace.Error($"Unexpected error occurred while sending StartMonitor message on socket!");
Trace.Error(e);
}
}
private void ConnectMonitor(string monitorSocketAddress)
{
int port = -1;
if (!_isMonitorConfigured && !String.IsNullOrEmpty(monitorSocketAddress))
{
try
{
string[] splitAddress = monitorSocketAddress.Split(':');
if (splitAddress.Length != 2)
{
Trace.Error("Invalid socket address {0}. Unable to connect to monitor.", monitorSocketAddress);
return;
}
IPAddress address;
try
{
address = IPAddress.Parse(splitAddress[0]);
}
catch (FormatException e)
{
Trace.Error("Invalid socket IP address {0}. Unable to connect to monitor.", splitAddress[0]);
Trace.Error(e);
return;
}
Int32.TryParse(splitAddress[1], out port);
if (port < IPEndPoint.MinPort || port > IPEndPoint.MaxPort)
{
Trace.Error("Invalid TCP socket port {0}. Unable to connect to monitor.", splitAddress[1]);
return;
}
Trace.Verbose("Trying to connect to monitor at port {0}", port);
_monitorSocket = new Socket(SocketType.Stream, ProtocolType.Tcp);
_monitorSocket.Connect(address, port);
Trace.Info("Connection successful to local port {0}", port);
_isMonitorConfigured = true;
}
catch (Exception e)
{
Trace.Error("Connection to monitor port {0} failed!", port);
Trace.Error(e);
}
}
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private void Dispose(bool disposing)
{
if (disposing)
{
if (_monitorSocket != null)
{
_monitorSocket.Send(Encoding.UTF8.GetBytes("<EOF>"));
_monitorSocket.Shutdown(SocketShutdown.Both);
_monitorSocket = null;
}
}
}
}
}