♻️ Remix things up

This commit is contained in:
2025-07-14 11:12:37 +08:00
parent 92ab7a1a2a
commit 06f1cc3ca1
9 changed files with 86 additions and 57 deletions

View File

@ -4,6 +4,7 @@ using DysonNetwork.Shared.Auth;
using DysonNetwork.Shared.Http;
using DysonNetwork.Shared.Registry;
using Microsoft.EntityFrameworkCore;
using tusdotnet.Stores;
var builder = WebApplication.CreateBuilder(args);
@ -18,6 +19,8 @@ builder.Services.AddAppAuthentication();
builder.Services.AddAppSwagger();
builder.Services.AddDysonAuth(builder.Configuration);
builder.Services.AddAppFileStorage(builder.Configuration);
// Add flush handlers and websocket handlers
builder.Services.AddAppFlushHandlers();
@ -36,8 +39,10 @@ using (var scope = app.Services.CreateScope())
await db.Database.MigrateAsync();
}
var tusDiskStore = app.Services.GetRequiredService<TusDiskStore>();
// Configure application middleware pipeline
app.ConfigureAppMiddleware(builder.Configuration);
app.ConfigureAppMiddleware(tusDiskStore);
// Configure gRPC
app.ConfigureGrpcServices();

View File

@ -1,8 +1,12 @@
using DysonNetwork.Drive.Storage;
using tusdotnet;
using tusdotnet.Interfaces;
namespace DysonNetwork.Drive.Startup;
public static class ApplicationBuilderExtensions
{
public static WebApplication ConfigureAppMiddleware(this WebApplication app, IConfiguration configuration)
public static WebApplication ConfigureAppMiddleware(this WebApplication app, ITusStore tusStore)
{
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
@ -15,13 +19,16 @@ public static class ApplicationBuilderExtensions
app.UseAuthorization();
app.MapControllers();
app.MapTus("/tus", _ => Task.FromResult(TusService.BuildConfiguration(tusStore)));
return app;
}
public static WebApplication ConfigureGrpcServices(this WebApplication app)
{
// Map your gRPC services here
// Example: app.MapGrpcService<MyGrpcService>();
app.MapGrpcService<FileServiceGrpc>();
app.MapGrpcService<FileReferenceServiceGrpc>();
return app;
}

View File

@ -1,6 +1,5 @@
using System.Text.Json;
using System.Threading.RateLimiting;
using dotnet_etcd.interfaces;
using DysonNetwork.Shared.Cache;
using Microsoft.AspNetCore.RateLimiting;
using Microsoft.OpenApi.Models;
@ -8,6 +7,7 @@ using NodaTime;
using NodaTime.Serialization.SystemTextJson;
using StackExchange.Redis;
using DysonNetwork.Shared.Proto;
using tusdotnet.Stores;
namespace DysonNetwork.Drive.Startup;
@ -123,9 +123,22 @@ public static class ServiceCollectionExtensions
return services;
}
public static IServiceCollection AddAppFileStorage(this IServiceCollection services, IConfiguration configuration)
{
var tusStorePath = configuration.GetSection("Tus").GetValue<string>("StorePath")!;
Directory.CreateDirectory(tusStorePath);
var tusDiskStore = new TusDiskStore(tusStorePath);
services.AddSingleton(tusDiskStore);
return services;
}
public static IServiceCollection AddAppBusinessServices(this IServiceCollection services)
{
// Add your business services here
services.AddScoped<Storage.FileService>();
services.AddScoped<Storage.FileReferenceService>();
return services;
}
}

View File

@ -1,6 +1,4 @@
using System.Threading.Tasks;
using DysonNetwork.Shared.Proto;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;
using NodaTime;
using Duration = NodaTime.Duration;
@ -13,13 +11,9 @@ namespace DysonNetwork.Drive.Storage
{
Instant? expiredAt = null;
if (request.ExpiredAt != null)
{
expiredAt = Instant.FromUnixTimeSeconds(request.ExpiredAt.Seconds);
}
else if (request.Duration != null)
{
expiredAt = SystemClock.Instance.GetCurrentInstant() + Duration.FromTimeSpan(request.Duration.ToTimeSpan());
}
var reference = await fileReferenceService.CreateReferenceAsync(
request.FileId,

View File

@ -1,4 +1,3 @@
using System.Threading.Tasks;
using DysonNetwork.Shared.Proto;
using Google.Protobuf.WellKnownTypes;
using Grpc.Core;

View File

@ -1,6 +1,7 @@
using System.Globalization;
using DysonNetwork.Pass.Wallet;
using DysonNetwork.Shared.Cache;
using DysonNetwork.Shared.Proto;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Localization;
using NodaTime;
@ -11,11 +12,20 @@ public class AccountEventService(
AppDatabase db,
PaymentService payment,
ICacheService cache,
IStringLocalizer<Localization.AccountEventResource> localizer
IStringLocalizer<Localization.AccountEventResource> localizer,
PusherService.PusherServiceClient pusher
)
{
private static readonly Random Random = new();
private const string StatusCacheKey = "AccountStatus_";
private const string StatusCacheKey = "account:status:";
private async Task<bool> GetAccountIsConnected(Guid userId)
{
var resp = await pusher.GetWebsocketConnectionStatusAsync(
new GetWebsocketConnectionStatusRequest { UserId = userId.ToString() }
);
return resp.IsConnected;
}
public void PurgeStatusCache(Guid userId)
{
@ -29,7 +39,7 @@ public class AccountEventService(
var cachedStatus = await cache.GetAsync<Status>(cacheKey);
if (cachedStatus is not null)
{
cachedStatus!.IsOnline = !cachedStatus.IsInvisible; // && ws.GetAccountIsConnected(userId);
cachedStatus!.IsOnline = !cachedStatus.IsInvisible && await GetAccountIsConnected(userId);
return cachedStatus;
}
@ -81,7 +91,7 @@ public class AccountEventService(
var cachedStatus = await cache.GetAsync<Status>(cacheKey);
if (cachedStatus != null)
{
cachedStatus.IsOnline = !cachedStatus.IsInvisible /* && ws.GetAccountIsConnected(userId) */;
cachedStatus.IsOnline = !cachedStatus.IsInvisible && await GetAccountIsConnected(userId);
results[userId] = cachedStatus;
}
else
@ -104,7 +114,7 @@ public class AccountEventService(
foreach (var status in statusesFromDb)
{
var isOnline = false; // ws.GetAccountIsConnected(status.AccountId);
var isOnline = await GetAccountIsConnected(status.AccountId);
status.IsOnline = !status.IsInvisible && isOnline;
results[status.AccountId] = status;
var cacheKey = $"{StatusCacheKey}{status.AccountId}";
@ -117,7 +127,7 @@ public class AccountEventService(
{
foreach (var userId in usersWithoutStatus)
{
var isOnline = false; // ws.GetAccountIsConnected(userId);
var isOnline = await GetAccountIsConnected(userId);
var defaultStatus = new Status
{
Attitude = StatusAttitude.Neutral,

View File

@ -15,6 +15,7 @@ builder.Services.AddAppMetrics();
// Add application services
builder.Services.AddRegistryService(builder.Configuration);
builder.Services.AddPusherService();
builder.Services.AddAppServices(builder.Configuration);
builder.Services.AddAppRateLimiting();
builder.Services.AddAppAuthentication();

View File

@ -182,8 +182,8 @@ message CreateReferenceRequest {
string file_id = 1;
string usage = 2;
string resource_id = 3;
google.protobuf.Timestamp expired_at = 4;
google.protobuf.Duration duration = 5; // Alternative to expired_at
optional google.protobuf.Timestamp expired_at = 4;
optional google.protobuf.Duration duration = 5; // Alternative to expired_at
}
message GetReferencesRequest {

View File

@ -13,8 +13,8 @@ public static class ServiceHelper
{
var etcdClient = sp.GetRequiredService<IEtcdClient>();
var config = sp.GetRequiredService<IConfiguration>();
var clientCertPath = config["Service:ClientCert"];
var clientKeyPath = config["Service:ClientKey"];
var clientCertPath = config["Service:ClientCert"]!;
var clientKeyPath = config["Service:ClientKey"]!;
var clientCertPassword = config["Service:CertPassword"];
return GrpcClientHelper
@ -32,8 +32,8 @@ public static class ServiceHelper
{
var etcdClient = sp.GetRequiredService<IEtcdClient>();
var config = sp.GetRequiredService<IConfiguration>();
var clientCertPath = config["Service:ClientCert"];
var clientKeyPath = config["Service:ClientKey"];
var clientCertPath = config["Service:ClientCert"]!;
var clientKeyPath = config["Service:ClientKey"]!;
var clientCertPassword = config["Service:CertPassword"];
return GrpcClientHelper