52 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
			
		
		
	
	
			52 lines
		
	
	
		
			1.8 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
using DysonNetwork.Shared.Cache;
 | 
						|
using Microsoft.EntityFrameworkCore;
 | 
						|
using Quartz;
 | 
						|
 | 
						|
namespace DysonNetwork.Sphere.Post;
 | 
						|
 | 
						|
public class PostViewFlushHandler(IServiceProvider serviceProvider) : IFlushHandler<PostViewInfo>
 | 
						|
{
 | 
						|
    public async Task FlushAsync(IReadOnlyList<Sphere.Post.PostViewInfo> items)
 | 
						|
    {
 | 
						|
        using var scope = serviceProvider.CreateScope();
 | 
						|
        var db = scope.ServiceProvider.GetRequiredService<AppDatabase>();
 | 
						|
        var cache = scope.ServiceProvider.GetRequiredService<ICacheService>();
 | 
						|
 | 
						|
        // Group views by post
 | 
						|
        var postViews = items
 | 
						|
            .GroupBy(x => x.PostId)
 | 
						|
            .ToDictionary(g => g.Key, g => g.ToList());
 | 
						|
 | 
						|
        // Calculate total views and unique views per post
 | 
						|
        foreach (var postId in postViews.Keys)
 | 
						|
        {
 | 
						|
            // Calculate unique views by distinct viewer IDs (not null)
 | 
						|
            var uniqueViews = postViews[postId]
 | 
						|
                .Where(v => !string.IsNullOrEmpty(v.ViewerId))
 | 
						|
                .Select(v => v.ViewerId)
 | 
						|
                .Distinct()
 | 
						|
                .Count();
 | 
						|
 | 
						|
            // Total views is just the count of all items for this post
 | 
						|
            var totalViews = postViews[postId].Count;
 | 
						|
 | 
						|
            // Update the post in the database
 | 
						|
            await db.Posts
 | 
						|
                .Where(p => p.Id == postId)
 | 
						|
                .ExecuteUpdateAsync(p => p
 | 
						|
                    .SetProperty(x => x.ViewsTotal, x => x.ViewsTotal + totalViews)
 | 
						|
                    .SetProperty(x => x.ViewsUnique, x => x.ViewsUnique + uniqueViews));
 | 
						|
 | 
						|
            // Invalidate any cache entries for this post
 | 
						|
            await cache.RemoveAsync($"post:{postId}");
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
public class PostViewFlushJob(FlushBufferService fbs, PostViewFlushHandler hdl) : IJob
 | 
						|
{
 | 
						|
    public async Task Execute(IJobExecutionContext context)
 | 
						|
    {
 | 
						|
        await fbs.FlushAsync(hdl);
 | 
						|
    }
 | 
						|
} |