Skip to content
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
43 changes: 43 additions & 0 deletions Refresh.Database/GameDatabaseContext.Workers.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
using Refresh.Database.Models.Workers;

namespace Refresh.Database;

public partial class GameDatabaseContext // Workers
{
public int CreateWorker()
{
DateTimeOffset now = this._time.Now;

// remove workers with this class so there's only one of us
this.Workers.RemoveRange(w => w.Class == WorkerClass.Refresh);

WorkerInfo worker = new()
{
Class = WorkerClass.Refresh,
CreatedAt = now,
LastContact = now,
};

this.Workers.Add(worker);
this.SaveChanges();

return worker.WorkerId;
}

/// <summary>
/// Mark a worker as contacted.
/// </summary>
/// <param name="id">Our worker ID.</param>
/// <returns>False if the worker doesn't exist, and the worker should shut down.</returns>
public bool MarkWorkerContacted(int id)
{
WorkerInfo? worker = this.Workers.FirstOrDefault(w => w.WorkerId == id);
if (worker == null)
return false;

worker.LastContact = this._time.Now;
this.SaveChanges();

return true;
}
}
2 changes: 2 additions & 0 deletions Refresh.Database/GameDatabaseContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
using MongoDB.Bson;
using NotEnoughLogs;
using Refresh.Database.Models.Statistics;
using Refresh.Database.Models.Workers;
using LogLevel = Microsoft.Extensions.Logging.LogLevel;

namespace Refresh.Database;
Expand Down Expand Up @@ -71,6 +72,7 @@ public partial class GameDatabaseContext : DbContext, IDatabaseContext
internal DbSet<PinProgressRelation> PinProgressRelations { get; set; }
internal DbSet<ProfilePinRelation> ProfilePinRelations { get; set; }
internal DbSet<GameSkillReward> GameSkillRewards { get; set; }
internal DbSet<WorkerInfo> Workers { get; set; }

#pragma warning disable CS8618 // Non-nullable variable must contain a non-null value when exiting constructor. Consider declaring it as nullable.
internal GameDatabaseContext(Logger logger, IDateTimeProvider time, IDatabaseConfig dbConfig)
Expand Down
41 changes: 41 additions & 0 deletions Refresh.Database/Migrations/20250721221859_AddWorkerInfoTable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
using System;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;

#nullable disable

namespace Refresh.Database.Migrations
{
[DbContext(typeof(GameDatabaseContext))]
[Migration("20250721221859_AddWorkerInfoTable")]
/// <inheritdoc />
public partial class AddWorkerInfoTable : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Workers",
columns: table => new
{
WorkerId = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Class = table.Column<int>(type: "integer", nullable: false),
CreatedAt = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false),
LastContact = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Workers", x => x.WorkerId);
});
}

/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Workers");
}
}
}
24 changes: 23 additions & 1 deletion Refresh.Database/Migrations/GameDatabaseContextModelSnapshot.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "9.0.6")
.HasAnnotation("ProductVersion", "9.0.7")
.HasAnnotation("Relational:MaxIdentifierLength", 63);

NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
Expand Down Expand Up @@ -1437,6 +1437,28 @@ protected override void BuildModel(ModelBuilder modelBuilder)
b.ToTable("QueuedRegistrations");
});

modelBuilder.Entity("Refresh.Database.Models.Workers.WorkerInfo", b =>
{
b.Property<int>("WorkerId")
.ValueGeneratedOnAdd()
.HasColumnType("integer");

NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("WorkerId"));

b.Property<int>("Class")
.HasColumnType("integer");

b.Property<DateTimeOffset>("CreatedAt")
.HasColumnType("timestamp with time zone");

b.Property<DateTimeOffset>("LastContact")
.HasColumnType("timestamp with time zone");

b.HasKey("WorkerId");

b.ToTable("Workers");
});

modelBuilder.Entity("Refresh.Database.Models.Activity.Event", b =>
{
b.HasOne("Refresh.Database.Models.Users.GameUser", "User")
Expand Down
13 changes: 13 additions & 0 deletions Refresh.Database/Models/Workers/WorkerClass.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Refresh.Database.Models.Workers;

public enum WorkerClass
{
/// <summary>
/// A worker based on the Refresh codebase.
/// </summary>
Refresh,
/// <summary>
/// A worker based on the CwLib codebase.
/// </summary>
Craftworld,
}
21 changes: 21 additions & 0 deletions Refresh.Database/Models/Workers/WorkerInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
namespace Refresh.Database.Models.Workers;

/// <summary>
/// Information and metadata about a worker.
/// </summary>
public class WorkerInfo
{
[Key, Required] public int WorkerId { get; set; }
/// <summary>
/// The class of worker this is. This determines what types of jobs this worker runs.
/// </summary>
public WorkerClass Class { get; set; }
/// <summary>
/// When did this worker come online?
/// </summary>
public DateTimeOffset CreatedAt { get; set; }
/// <summary>
/// When is the last time we heard from this worker?
/// </summary>
public DateTimeOffset LastContact { get; set; }
}
14 changes: 4 additions & 10 deletions Refresh.GameServer/RefreshGameServer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
using Refresh.Interfaces.Game;
using Refresh.Interfaces.Internal;
using Refresh.Interfaces.Workers;
using Refresh.Interfaces.Workers.RequestTracking;
using Refresh.Interfaces.Workers.Workers;
using Refresh.Interfaces.Workers.Repeating;
using Refresh.Workers;

namespace Refresh.GameServer;

Expand Down Expand Up @@ -206,17 +206,11 @@ protected override void SetupServices()

protected virtual void SetupWorkers()
{
this.WorkerManager = new WorkerManager(this.Logger, this._dataStore, this._databaseProvider, this._matchService, this._guidCheckerService);

this.WorkerManager.AddWorker<PunishmentExpiryWorker>();
this.WorkerManager.AddWorker<ExpiredObjectWorker>();
this.WorkerManager.AddWorker<CoolLevelsWorker>();
this.WorkerManager.AddWorker<RequestStatisticSubmitWorker>();
this.WorkerManager.AddWorker<ObjectStatisticsWorker>();
this.WorkerManager = RefreshWorkerManager.Create(this.Logger, this._dataStore, this._databaseProvider);

if ((this._integrationConfig?.DiscordWebhookEnabled ?? false) && this._config != null && this._config.PermitShowingOnlineUsers)
{
this.WorkerManager.AddWorker(new DiscordIntegrationWorker(this._integrationConfig, this._config));
this.WorkerManager.AddJob(new DiscordIntegrationJob(this._integrationConfig, this._config));
}
}

Expand Down
20 changes: 0 additions & 20 deletions Refresh.Interfaces.Workers/IWorker.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

<ItemGroup>
<ProjectReference Include="..\Refresh.Core\Refresh.Core.csproj" />
<ProjectReference Include="..\Refresh.Interfaces.APIv3\Refresh.Interfaces.APIv3.csproj" />
<ProjectReference Include="..\Refresh.Workers\Refresh.Workers.csproj" />
</ItemGroup>

</Project>
23 changes: 23 additions & 0 deletions Refresh.Interfaces.Workers/RefreshWorkerManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using Bunkum.Core.Storage;
using NotEnoughLogs;
using Refresh.Database;
using Refresh.Interfaces.Workers.Repeating;
using Refresh.Workers;

namespace Refresh.Interfaces.Workers;

public static class RefreshWorkerManager
{
public static WorkerManager Create(Logger logger, IDataStore dataStore, GameDatabaseProvider databaseProvider)
{
WorkerManager manager = new(logger, dataStore, databaseProvider);

manager.AddJob<PunishmentExpiryJob>();
manager.AddJob<CleanupExpiredObjectsJob>();
manager.AddJob<CoolLevelsJob>();
manager.AddJob<RequestStatisticSubmitJob>();
manager.AddJob<ObjectStatisticsJob>();

return manager;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@
using System.Diagnostics.CodeAnalysis;
using NotEnoughLogs;
using Refresh.Core;
using Refresh.Core.Types.Data;
using Refresh.Database;
using Refresh.Database.Models.Authentication;
using Refresh.Database.Models.Levels;
using Refresh.Database.Models.Users;
using Refresh.Workers;

namespace Refresh.Interfaces.Workers.Workers;
namespace Refresh.Interfaces.Workers.Repeating;

public class CoolLevelsWorker : IWorker
public class CoolLevelsJob : RepeatingJob
{
public int WorkInterval => 600_000; // Every 10 minutes
protected override int Interval => 600_000; // Every 10 minutes

[SuppressMessage("ReSharper.DPA", "DPA0005: Database issues")]
public void DoWork(DataContext context)
public override void ExecuteJob(WorkContext context)
{
const int pageSize = 1000;
DatabaseList<GameLevel> levels = context.Database.GetUserLevelsChunk(0, pageSize);
Expand Down Expand Up @@ -104,7 +104,7 @@ private static float CalculateLevelDecayMultiplier(Logger logger, long now, Game
return (float)multiplier;
}

private static float CalculatePositiveScore(GameLevel level, DataContext context)
private static float CalculatePositiveScore(GameLevel level, WorkContext context)
{
Debug.Assert(level.Statistics != null);

Expand Down Expand Up @@ -163,7 +163,7 @@ private static float CalculatePositiveScore(GameLevel level, DataContext context
return score;
}

private static float CalculateNegativeScore(GameLevel level, DataContext context)
private static float CalculateNegativeScore(GameLevel level, WorkContext context)
{
Debug.Assert(level.Statistics != null);

Expand Down
Loading