Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Network monitoring refactor #1079

Merged
merged 3 commits into from
Aug 11, 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
31 changes: 31 additions & 0 deletions Shoko.Plugin.Abstractions/Enums/NetworkAvailibility.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@

namespace Shoko.Plugin.Abstractions.Enums
{
public enum NetworkAvailability
{
/// <summary>
/// Shoko was unable to find any network interfaces.
/// </summary>
NoInterfaces = 0,

/// <summary>
/// Shoko was unable to find any local gateways to use.
/// </summary>
NoGateways,

/// <summary>
/// Shoko was able to find a local gateway.
/// </summary>
LocalOnly,

/// <summary>
/// Shoko was able to connect to some internet endpoints in WAN.
/// </summary>
PartialInternet,

/// <summary>
/// Shoko was able to connect to all internet endpoints in WAN.
/// </summary>
Internet,
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System;
using Shoko.Plugin.Abstractions.Enums;

namespace Shoko.Plugin.Abstractions
{
public class NetworkAvailabilityChangedEventArgs : EventArgs
{
/// <summary>
/// The new network availibility.
/// </summary>
public NetworkAvailability NetworkAvailability { get; }

public NetworkAvailabilityChangedEventArgs(NetworkAvailability networkAvailability)
{
NetworkAvailability = networkAvailability;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Shoko.Plugin.Abstractions.Enums;

namespace Shoko.Plugin.Abstractions.Extensions
{
public static class NetworkAvailabilityExtensions
{
public static bool HasInternet(this NetworkAvailability value)
=> value is NetworkAvailability.Internet or NetworkAvailability.PartialInternet;
}
}
37 changes: 37 additions & 0 deletions Shoko.Plugin.Abstractions/Services/IConnectivityService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@

using System;
using Shoko.Plugin.Abstractions.Enums;

namespace Shoko.Plugin.Abstractions.Services
{
/// <summary>
/// A service used to check or monitor the current network availability.
/// </summary>
public interface IConnectivityService
{
/// <summary>
/// Dispatched when the network availibility has changed.
/// </summary>
event EventHandler<NetworkAvailabilityChangedEventArgs> NetworkAvailabilityChanged;

/// <summary>
/// Current network availibility.
/// </summary>
public NetworkAvailability NetworkAvailability { get; }

/// <summary>
/// Is the AniDB UDP API currently reachable?
/// </summary>
public bool IsAniDBUdpReachable { get; }

/// <summary>
/// Are we currently banned from using the AniDB HTTP API?
/// </summary>
public bool IsAniDBHttpBanned { get; }

/// <summary>
/// Are we currently banned from using the AniDB UDP API?
/// </summary>
public bool IsAniDBUdpBanned { get; }
}
}
2 changes: 2 additions & 0 deletions Shoko.Server/API/APIExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
using ShokoEventEmitter = Shoko.Server.API.SignalR.Aggregate.ShokoEventEmitter;
using QueueEmitter = Shoko.Server.API.SignalR.Aggregate.QueueEmitter;
using AVDumpEmitter = Shoko.Server.API.SignalR.Aggregate.AVDumpEmitter;
using NetworkEmitter = Shoko.Server.API.SignalR.Aggregate.NetworkEmitter;
using LegacyAniDBEmitter = Shoko.Server.API.SignalR.Legacy.AniDBEmitter;
using LegacyQueueEmitter = Shoko.Server.API.SignalR.Legacy.QueueEmitter;
using LegacyShokoEventEmitter = Shoko.Server.API.SignalR.Legacy.ShokoEventEmitter;
Expand All @@ -47,6 +48,7 @@ public static IServiceCollection AddAPI(this IServiceCollection services)
services.AddSingleton<AniDBEmitter>();
services.AddSingleton<ShokoEventEmitter>();
services.AddSingleton<AVDumpEmitter>();
services.AddSingleton<NetworkEmitter>();
services.AddSingleton<QueueEmitter>();

services.AddAuthentication(options =>
Expand Down
9 changes: 8 additions & 1 deletion Shoko.Server/API/SignalR/Aggregate/AggregateHub.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,15 @@ public class AggregateHub : Hub

private readonly AVDumpEmitter _avdumpEmitter;

public AggregateHub(AniDBEmitter aniDBEmitter, QueueEmitter queueEmitter, ShokoEventEmitter shokoEmitter, AVDumpEmitter avdumpEmitter)
private readonly NetworkEmitter _networkEmitter;

public AggregateHub(AniDBEmitter aniDBEmitter, QueueEmitter queueEmitter, ShokoEventEmitter shokoEmitter, AVDumpEmitter avdumpEmitter, NetworkEmitter networkEmitter)
{
_aniDBEmitter = aniDBEmitter;
_queueEmitter = queueEmitter;
_shokoEmitter = shokoEmitter;
_avdumpEmitter = avdumpEmitter;
_networkEmitter = networkEmitter;
}

public override async Task OnConnectedAsync()
Expand Down Expand Up @@ -56,6 +59,10 @@ public override async Task OnConnectedAsync()
await Groups.AddToGroupAsync(Context.ConnectionId, _avdumpEmitter.Group);
await Clients.Caller.SendAsync(_avdumpEmitter.GetName(OnConnected), _avdumpEmitter.GetInitialMessage());
break;
case "network":
await Groups.AddToGroupAsync(Context.ConnectionId, _networkEmitter.Group);
await Clients.Caller.SendAsync(_networkEmitter.GetName(OnConnected), _networkEmitter.GetInitialMessage());
break;
}
}
}
Expand Down
33 changes: 33 additions & 0 deletions Shoko.Server/API/SignalR/Aggregate/NetworkEmitter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using System;
using Microsoft.AspNetCore.SignalR;
using Shoko.Plugin.Abstractions;
using Shoko.Plugin.Abstractions.Services;
using Shoko.Server.API.SignalR.Models;

namespace Shoko.Server.API.SignalR.Aggregate;

public class NetworkEmitter : BaseEmitter, IDisposable
{
private IConnectivityService EventHandler { get; set; }

public NetworkEmitter(IHubContext<AggregateHub> hub, IConnectivityService events) : base(hub)
{
EventHandler = events;
EventHandler.NetworkAvailabilityChanged += OnNetworkAvailabilityChanged;
}

public void Dispose()
{
EventHandler.NetworkAvailabilityChanged -= OnNetworkAvailabilityChanged;
}

private async void OnNetworkAvailabilityChanged(object sender, NetworkAvailabilityChangedEventArgs eventArgs)
{
await SendAsync("NetworkAvailabilityChanged", new NetworkAvailabilitySignalRModel(eventArgs));
}

public override object GetInitialMessage()
{
return new NetworkAvailabilitySignalRModel(EventHandler.NetworkAvailability);
}
}
25 changes: 25 additions & 0 deletions Shoko.Server/API/SignalR/Models/NetworkAvailabilitySignalRModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Shoko.Plugin.Abstractions;
using Shoko.Plugin.Abstractions.Enums;

namespace Shoko.Server.API.SignalR.Models;

public class NetworkAvailabilitySignalRModel
{
/// <summary>
/// The current network availability.
/// </summary>
[JsonConverter(typeof(StringEnumConverter))]
public NetworkAvailability NetworkAvailability { get; }

public NetworkAvailabilitySignalRModel(NetworkAvailability networkAvailability)
{
NetworkAvailability = networkAvailability;
}

public NetworkAvailabilitySignalRModel(NetworkAvailabilityChangedEventArgs eventArgs)
{
NetworkAvailability = eventArgs.NetworkAvailability;
}
}
28 changes: 11 additions & 17 deletions Shoko.Server/API/v3/Controllers/QueueController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Shoko.Plugin.Abstractions.Services;
using Shoko.Server.API.Annotations;
using Shoko.Server.API.v3.Helpers;
using Shoko.Server.API.v3.Models.Common;
using Shoko.Server.API.v3.Models.Shoko;
using Shoko.Server.Commands.Generic;
using Shoko.Server.Providers.AniDB.Interfaces;
using Shoko.Server.Repositories;
using Shoko.Server.Server;
using Shoko.Server.Settings;
Expand All @@ -37,15 +37,12 @@ public class QueueController : BaseController

private readonly ILogger<InitController> _logger;

private readonly IUDPConnectionHandler _udpHandler;
private readonly IConnectivityService _connectivityService;

private readonly IHttpConnectionHandler _httpHandler;

public QueueController(ILogger<InitController> logger, ISettingsProvider settingsProvider, IUDPConnectionHandler udpHandler, IHttpConnectionHandler httpHandler) : base(settingsProvider)
public QueueController(ILogger<InitController> logger, ISettingsProvider settingsProvider, IConnectivityService connectivityService) : base(settingsProvider)
{
_logger = logger;
_udpHandler = udpHandler;
_httpHandler = httpHandler;
_connectivityService = connectivityService;
}

/// <summary>
Expand Down Expand Up @@ -204,19 +201,16 @@ public ActionResult ClearQueueByName([FromRoute] string queueName)
if (processor == null)
return NotFound(NoQueueWithName);

var httpBanned = _httpHandler.IsBanned;
var udpBanned = _udpHandler.IsBanned;
var udpUnavailable = _udpHandler.IsNetworkAvailable;
return queueName.ToLowerInvariant() switch
{
"general" => RepoFactory.CommandRequest.GetNextGeneralCommandRequests(_udpHandler, _httpHandler, showAll)
.ToListResult(queueItem => new Queue.QueueItem(processor, queueItem, httpBanned, udpBanned, udpUnavailable), page, pageSize),
"general" => RepoFactory.CommandRequest.GetNextGeneralCommandRequests(_connectivityService, showAll)
.ToListResult(queueItem => new Queue.QueueItem(processor, queueItem, _connectivityService), page, pageSize),

"hasher" => RepoFactory.CommandRequest.GetNextHasherCommandRequests()
.ToListResult(queueItem => new Queue.QueueItem(processor, queueItem, httpBanned, udpBanned, udpUnavailable), page, pageSize),
.ToListResult(queueItem => new Queue.QueueItem(processor, queueItem, _connectivityService), page, pageSize),

"image" => RepoFactory.CommandRequest.GetNextImagesCommandRequests()
.ToListResult(queueItem => new Queue.QueueItem(processor, queueItem, httpBanned, udpBanned, udpUnavailable), page, pageSize),
"image" => RepoFactory.CommandRequest.GetNextImagesCommandRequests(_connectivityService, showAll)
.ToListResult(queueItem => new Queue.QueueItem(processor, queueItem, _connectivityService), page, pageSize),

_ => NotFound(NoQueueWithName),
};
Expand All @@ -233,15 +227,15 @@ public ActionResult<Dictionary<CommandRequestType, int>> GetTypesForItemsInQueue
{
return queueName.ToLowerInvariant() switch
{
"general" => RepoFactory.CommandRequest.GetNextGeneralCommandRequests(_udpHandler, _httpHandler, true)
"general" => RepoFactory.CommandRequest.GetNextGeneralCommandRequests(_connectivityService, true)
.GroupBy(a => (CommandRequestType)a.CommandType)
.ToDictionary(a => a.Key, a => a.Count()),

"hasher" => RepoFactory.CommandRequest.GetNextHasherCommandRequests()
.GroupBy(a => (CommandRequestType)a.CommandType)
.ToDictionary(a => a.Key, a => a.Count()),

"image" => RepoFactory.CommandRequest.GetNextImagesCommandRequests()
"image" => RepoFactory.CommandRequest.GetNextImagesCommandRequests(_connectivityService, true)
.GroupBy(a => (CommandRequestType)a.CommandType)
.ToDictionary(a => a.Key, a => a.Count()),

Expand Down
5 changes: 3 additions & 2 deletions Shoko.Server/API/v3/Models/Shoko/Queue.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
using Shoko.Models.Server;
using Shoko.Plugin.Abstractions.Services;
using Shoko.Server.Commands.Generic;
using Shoko.Server.Server;

Expand Down Expand Up @@ -93,13 +94,13 @@ public class QueueItem
/// </summary>
public bool IsDisabled { get; }

public QueueItem(CommandProcessor processor, CommandRequest request, bool httpBanned, bool udpBanned, bool udpUnavailable)
public QueueItem(CommandProcessor processor, CommandRequest request, IConnectivityService connectivityService)
{
ID = request.CommandRequestID;
Name = request.CommandID;
Type = (CommandRequestType)request.CommandType;
IsRunning = processor.CurrentCommand != null && processor.CurrentCommand.CommandRequestID == request.CommandRequestID;
IsDisabled = Repositories.RepoFactory.CommandRequest.CheckIfCommandRequestIsDisabled(Type, httpBanned, udpBanned, udpUnavailable);
IsDisabled = Repositories.RepoFactory.CommandRequest.CheckIfCommandRequestIsDisabled(Type, connectivityService);
}
}

Expand Down
Loading