| | | 1 | | using System; |
| | | 2 | | using System.Threading.Tasks; |
| | | 3 | | |
| | | 4 | | namespace Services.OzonWebhookServices.Monitoring |
| | | 5 | | { |
| | | 6 | | /// <summary> |
| | | 7 | | /// Последний снимок доступности пуш-адресов Ozon в памяти процесса (singleton). |
| | | 8 | | /// Баннер админа читает его без обращения к Ozon; обновляет джоб <see cref="OzonWebhookAvailabilityJob"/>. |
| | | 9 | | /// </summary> |
| | | 10 | | public sealed class OzonWebhookAvailabilityStore |
| | | 11 | | { |
| | 3 | 12 | | private readonly object _gate = new(); |
| | 3 | 13 | | private OzonWebhookAvailabilitySnapshot _snapshot = OzonWebhookAvailabilitySnapshot.Empty; |
| | | 14 | | private string? _alertedSignature; |
| | | 15 | | private Task<OzonWebhookAvailabilitySnapshot>? _inFlight; |
| | | 16 | | |
| | | 17 | | public OzonWebhookAvailabilitySnapshot Current |
| | | 18 | | { |
| | 0 | 19 | | get { lock (_gate) return _snapshot; } |
| | | 20 | | } |
| | | 21 | | |
| | | 22 | | public void Set(OzonWebhookAvailabilitySnapshot snapshot) |
| | | 23 | | { |
| | 0 | 24 | | lock (_gate) _snapshot = snapshot; |
| | 0 | 25 | | } |
| | | 26 | | |
| | | 27 | | /// <summary> |
| | | 28 | | /// Единый общий запрос к Ozon: пока он идёт, остальные вызовы получают тот же <see cref="Task"/> |
| | | 29 | | /// (несколько вкладок/пользователей одновременно не множат запросы к API). |
| | | 30 | | /// </summary> |
| | | 31 | | public Task<OzonWebhookAvailabilitySnapshot> GetOrStartRefresh(Func<Task<OzonWebhookAvailabilitySnapshot>> start |
| | | 32 | | { |
| | 0 | 33 | | lock (_gate) |
| | | 34 | | { |
| | 0 | 35 | | if (_inFlight is { IsCompleted: false }) |
| | 0 | 36 | | return _inFlight; |
| | 0 | 37 | | return _inFlight = start(); |
| | | 38 | | } |
| | 0 | 39 | | } |
| | | 40 | | |
| | | 41 | | /// <summary> |
| | | 42 | | /// true, если набор проблем изменился с прошлого оповещения (в т.ч. пропал — тогда подпись пустая). |
| | | 43 | | /// Запоминает подпись, поэтому повторный вызов с тем же набором вернёт false. |
| | | 44 | | /// </summary> |
| | | 45 | | public bool TryMarkAlerted(string signature, out bool wasProblem) |
| | | 46 | | { |
| | 8 | 47 | | lock (_gate) |
| | | 48 | | { |
| | 8 | 49 | | wasProblem = !string.IsNullOrEmpty(_alertedSignature); |
| | 8 | 50 | | if (string.Equals(_alertedSignature ?? string.Empty, signature, StringComparison.Ordinal)) |
| | 4 | 51 | | return false; |
| | 4 | 52 | | _alertedSignature = signature; |
| | 4 | 53 | | return true; |
| | | 54 | | } |
| | 8 | 55 | | } |
| | | 56 | | } |
| | | 57 | | } |