♻️ Update the usage counting since the pool id logic changed

This commit is contained in:
2026-01-13 23:26:09 +08:00
parent 5a99665e4e
commit fc1edf0ea3
13 changed files with 833 additions and 231 deletions

View File

@@ -1,5 +1,6 @@
using Microsoft.EntityFrameworkCore;
using NodaTime;
using DysonNetwork.Shared.Models;
namespace DysonNetwork.Drive.Billing;
@@ -29,28 +30,42 @@ public class UsageService(AppDatabase db)
public async Task<TotalUsageDetails> GetTotalUsage(Guid accountId)
{
var now = SystemClock.Instance.GetCurrentInstant();
var fileQuery = db.Files
.Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
.Where(f => f.AccountId == accountId)
.AsQueryable();
var poolUsages = await db.Pools
.Select(p => new UsageDetails
{
PoolId = p.Id,
PoolName = p.Name,
UsageBytes = fileQuery
.Where(f => f.PoolId == p.Id)
.Include(f => f.Object)
.Sum(f => f.Size),
Cost = fileQuery
.Where(f => f.PoolId == p.Id)
.Include(f => f.Object)
.Sum(f => f.Size) / 1024.0 / 1024.0 *
(p.BillingConfig.CostMultiplier ?? 1.0),
FileCount = fileQuery
.Count(f => f.PoolId == p.Id)
UsageBytes = db.Files
.Where(f => f.AccountId == accountId)
.Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
.SelectMany(f => f.Object!.FileReplicas
.Where(r => r.PoolId == p.Id && r.Status == SnFileReplicaStatus.Available))
.Join(db.FileObjects,
r => r.ObjectId,
o => o.Id,
(r, o) => o.Size)
.DefaultIfEmpty(0L)
.Sum(),
Cost = db.Files
.Where(f => f.AccountId == accountId)
.Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
.SelectMany(f => f.Object!.FileReplicas
.Where(r => r.PoolId == p.Id && r.Status == SnFileReplicaStatus.Available))
.Join(db.FileObjects,
r => r.ObjectId,
o => o.Id,
(r, o) => new { Size = o.Size, Multiplier = p.BillingConfig.CostMultiplier ?? 1.0 })
.Sum(x => x.Size * x.Multiplier) / 1024.0 / 1024.0,
FileCount = db.Files
.Where(f => f.AccountId == accountId)
.Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
.SelectMany(f => f.Object!.FileReplicas
.Where(r => r.PoolId == p.Id && r.Status == SnFileReplicaStatus.Available))
.Count()
})
.ToListAsync();
@@ -75,18 +90,22 @@ public class UsageService(AppDatabase db)
}
var now = SystemClock.Instance.GetCurrentInstant();
var fileQuery = db.Files
.Where(f => !f.IsMarkedRecycle)
.Where(f => f.ExpiredAt.HasValue && f.ExpiredAt > now)
var replicaQuery = db.Files
.Where(f => f.AccountId == accountId)
.AsQueryable();
.Where(f => !f.IsMarkedRecycle)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
.SelectMany(f => f.Object!.FileReplicas
.Where(r => r.PoolId == poolId && r.Status == SnFileReplicaStatus.Available));
var usageBytes = await fileQuery
.Include(f => f.Object)
.SumAsync(f => f.Size);
var usageBytes = await replicaQuery
.Join(db.FileObjects,
r => r.ObjectId,
o => o.Id,
(r, o) => o.Size)
.DefaultIfEmpty(0L)
.SumAsync();
var fileCount = await fileQuery
.CountAsync();
var fileCount = await replicaQuery.CountAsync();
var cost = usageBytes / 1024.0 / 1024.0 *
(pool.BillingConfig.CostMultiplier ?? 1.0);
@@ -104,22 +123,24 @@ public class UsageService(AppDatabase db)
public async Task<long> GetTotalBillableUsage(Guid accountId)
{
var now = SystemClock.Instance.GetCurrentInstant();
var files = await db.Files
.Where(f => f.AccountId == accountId)
.Where(f => f.PoolId.HasValue)
.Where(f => !f.IsMarkedRecycle)
.Include(f => f.Pool)
.Include(f => f.Object)
.Where(f => !f.ExpiredAt.HasValue || f.ExpiredAt > now)
.Select(f => new
var billingData = await (from f in db.Files
where f.AccountId == accountId
where !f.IsMarkedRecycle
where !f.ExpiredAt.HasValue || f.ExpiredAt > now
from r in f.Object!.FileReplicas
where r.Status == SnFileReplicaStatus.Available
where r.PoolId.HasValue
join p in db.Pools on r.PoolId equals p.Id
join o in db.FileObjects on r.ObjectId equals o.Id
select new
{
f.Size,
Multiplier = f.Pool!.BillingConfig.CostMultiplier ?? 1.0
})
.ToListAsync();
Size = o.Size,
Multiplier = p.BillingConfig.CostMultiplier ?? 1.0
}).ToListAsync();
var totalCost = files.Sum(f => f.Size * f.Multiplier) / 1024.0 / 1024.0;
var totalCost = billingData.Sum(x => x.Size * x.Multiplier) / 1024.0 / 1024.0;
return (long)Math.Ceiling(totalCost);
}
}
}