Skip to content

Commit

Permalink
Try catch around HostedServices
Browse files Browse the repository at this point in the history
  • Loading branch information
Tides committed Jan 20, 2024
1 parent 34b4833 commit 342a981
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 23 deletions.
2 changes: 0 additions & 2 deletions Obsidian.API/Events/BaseMinecraftEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ public abstract class BaseMinecraftEventArgs : AsyncEventArgs
/// </summary>
public IServer Server { get; }

public static EventType EventType { get; }

/// <summary>
/// Constructs a new instance of the <see cref="BaseMinecraftEventArgs"/> class.
/// </summary>
Expand Down
34 changes: 22 additions & 12 deletions Obsidian/Services/PacketBroadcaster.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Obsidian.Entities;
using Obsidian.Hosting;
using Obsidian.Net.Packets;
using Obsidian.WorldData;
using System.Threading;
Expand All @@ -9,12 +10,14 @@ namespace Obsidian.Services;
public sealed class PacketBroadcaster : BackgroundService, IPacketBroadcaster
{
private readonly IServer server;
private readonly IServerEnvironment environment;
private readonly PriorityQueue<QueuedPacket, int> priorityQueue = new();
private readonly ILogger logger;

public PacketBroadcaster(IServer server, ILoggerFactory loggerFactory)
public PacketBroadcaster(IServer server, ILoggerFactory loggerFactory, IServerEnvironment environment)
{
this.server = server;
this.environment = environment;
this.logger = loggerFactory.CreateLogger<PacketBroadcaster>();
}

Expand Down Expand Up @@ -49,21 +52,28 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
using var timer = new PeriodicTimer(TimeSpan.FromMilliseconds(20));

while (await timer.WaitForNextTickAsync(stoppingToken))
try
{
if (!this.priorityQueue.TryDequeue(out var queuedPacket, out _))
continue;

if (queuedPacket.ToWorld is World toWorld)
while (await timer.WaitForNextTickAsync(stoppingToken))
{
foreach (var player in toWorld.Players.Values.Where(player => queuedPacket.ExcludedIds != null && !queuedPacket.ExcludedIds.Contains(player.EntityId)))
await player.client.QueuePacketAsync(queuedPacket.Packet);
if (!this.priorityQueue.TryDequeue(out var queuedPacket, out _))
continue;

continue;
}
if (queuedPacket.ToWorld is World toWorld)
{
foreach (var player in toWorld.Players.Values.Where(player => queuedPacket.ExcludedIds != null && !queuedPacket.ExcludedIds.Contains(player.EntityId)))
await player.client.QueuePacketAsync(queuedPacket.Packet);

continue;
}

foreach (var player in this.server.Players.Cast<Player>().Where(player => queuedPacket.ExcludedIds != null && !queuedPacket.ExcludedIds.Contains(player.EntityId)))
await player.client.QueuePacketAsync(queuedPacket.Packet);
foreach (var player in this.server.Players.Cast<Player>().Where(player => queuedPacket.ExcludedIds != null && !queuedPacket.ExcludedIds.Contains(player.EntityId)))
await player.client.QueuePacketAsync(queuedPacket.Packet);
}
}
catch (Exception e)
{
await this.environment.OnServerCrashAsync(this.logger, e);
}
}

Expand Down
26 changes: 17 additions & 9 deletions Obsidian/WorldData/WorldManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,25 @@ protected async override Task ExecuteAsync(CancellationToken stoppingToken)
{
var timer = new BalancingTimer(20, stoppingToken);

this.RegisterDefaults();
// TODO: This should defenitly accept a cancellation token.
// If Cancel is called, this method should stop within the configured timeout, otherwise code execution will simply stop here,
// and server shutdown will not be handled correctly.
// Load worlds on startup.
await this.LoadWorldsAsync();

while (await timer.WaitForNextTickAsync())
try
{
await Task.WhenAll(this.worlds.Values.Cast<World>().Select(x => x.ManageChunksAsync()));
this.RegisterDefaults();
// TODO: This should defenitly accept a cancellation token.
// If Cancel is called, this method should stop within the configured timeout, otherwise code execution will simply stop here,
// and server shutdown will not be handled correctly.
// Load worlds on startup.
await this.LoadWorldsAsync();

while (await timer.WaitForNextTickAsync())
{
await Task.WhenAll(this.worlds.Values.Cast<World>().Select(x => x.ManageChunksAsync()));
}
}
catch (Exception ex)
{
await this.serverEnvironment.OnServerCrashAsync(this.logger, ex);
}

}

/// <summary>
Expand Down

0 comments on commit 342a981

Please sign in to comment.