2021-10-28 21:26:57 +01:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
2021-10-28 23:05:07 +01:00
|
|
|
using System.Text.Json;
|
2021-10-28 21:26:57 +01:00
|
|
|
using System.Threading;
|
|
|
|
using System.Threading.Tasks;
|
|
|
|
using Microsoft.Extensions.Logging;
|
|
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
2021-10-29 22:35:34 +01:00
|
|
|
|
2021-10-28 23:05:07 +01:00
|
|
|
using StackExchange.Redis;
|
2021-10-28 21:26:57 +01:00
|
|
|
|
|
|
|
namespace Selector.Cache
|
|
|
|
{
|
2022-06-28 07:30:27 +01:00
|
|
|
public class CacheWriter : IPlayerConsumer
|
2021-10-28 21:26:57 +01:00
|
|
|
{
|
|
|
|
private readonly IPlayerWatcher Watcher;
|
2021-10-28 23:05:07 +01:00
|
|
|
private readonly IDatabaseAsync Db;
|
|
|
|
private readonly ILogger<CacheWriter> Logger;
|
2021-11-30 20:38:26 +00:00
|
|
|
public TimeSpan CacheExpiry { get; set; } = TimeSpan.FromMinutes(20);
|
2021-10-28 21:26:57 +01:00
|
|
|
|
|
|
|
public CancellationToken CancelToken { get; set; }
|
|
|
|
|
2021-10-28 23:05:07 +01:00
|
|
|
public CacheWriter(
|
2021-10-28 21:26:57 +01:00
|
|
|
IPlayerWatcher watcher,
|
2021-10-28 23:05:07 +01:00
|
|
|
IDatabaseAsync db,
|
|
|
|
ILogger<CacheWriter> logger = null,
|
2021-10-28 21:26:57 +01:00
|
|
|
CancellationToken token = default
|
|
|
|
){
|
|
|
|
Watcher = watcher;
|
2021-10-28 23:05:07 +01:00
|
|
|
Db = db;
|
|
|
|
Logger = logger ?? NullLogger<CacheWriter>.Instance;
|
2021-10-28 21:26:57 +01:00
|
|
|
CancelToken = token;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Callback(object sender, ListeningChangeEventArgs e)
|
|
|
|
{
|
|
|
|
if (e.Current is null) return;
|
2021-10-29 22:35:34 +01:00
|
|
|
|
2021-12-18 23:06:21 +00:00
|
|
|
Task.Run(async () => {
|
|
|
|
try
|
|
|
|
{
|
|
|
|
await AsyncCallback(e);
|
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
Logger.LogError(e, "Error occured during callback");
|
|
|
|
}
|
|
|
|
|
|
|
|
}, CancelToken);
|
2021-10-28 21:26:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public async Task AsyncCallback(ListeningChangeEventArgs e)
|
|
|
|
{
|
2022-07-01 22:04:17 +01:00
|
|
|
using var scope = Logger.GetListeningEventArgsScope(e);
|
|
|
|
|
2021-12-21 22:22:52 +00:00
|
|
|
var payload = JsonSerializer.Serialize((CurrentlyPlayingDTO) e, JsonContext.Default.CurrentlyPlayingDTO);
|
2021-10-29 22:35:34 +01:00
|
|
|
|
2022-07-01 22:04:17 +01:00
|
|
|
Logger.LogTrace("Caching current");
|
2021-10-29 22:35:34 +01:00
|
|
|
|
2021-11-11 19:54:28 +00:00
|
|
|
var resp = await Db.StringSetAsync(Key.CurrentlyPlaying(e.Id), payload, expiry: CacheExpiry);
|
2021-10-29 22:35:34 +01:00
|
|
|
|
2022-07-01 22:04:17 +01:00
|
|
|
Logger.LogDebug("Cached current, {state}", (resp ? "value set" : "value NOT set"));
|
2021-10-29 22:35:34 +01:00
|
|
|
|
2021-10-28 21:26:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public void Subscribe(IWatcher watch = null)
|
|
|
|
{
|
|
|
|
var watcher = watch ?? Watcher ?? throw new ArgumentNullException("No watcher provided");
|
|
|
|
|
|
|
|
if (watcher is IPlayerWatcher watcherCast)
|
|
|
|
{
|
|
|
|
watcherCast.ItemChange += Callback;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new ArgumentException("Provided watcher is not a PlayerWatcher");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void Unsubscribe(IWatcher watch = null)
|
|
|
|
{
|
|
|
|
var watcher = watch ?? Watcher ?? throw new ArgumentNullException("No watcher provided");
|
|
|
|
|
|
|
|
if (watcher is IPlayerWatcher watcherCast)
|
|
|
|
{
|
|
|
|
watcherCast.ItemChange -= Callback;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
throw new ArgumentException("Provided watcher is not a PlayerWatcher");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|