-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathLogTap.cs
More file actions
70 lines (59 loc) · 2.08 KB
/
Copy pathLogTap.cs
File metadata and controls
70 lines (59 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
using System;
using System.Collections.Generic;
using System.Threading.Channels;
namespace CMDownloaderUI
{
internal static class LogTap
{
private static readonly object _lock = new();
private static readonly Queue<string> _q = new(capacity: 2048);
private const int MaxLines = 2048;
// 👇 NEW: a list of live listeners for SSE
private static readonly List<Channel<string>> _listeners = new();
public static void Append(string line)
{
if (line == null) return;
var msg = $"{DateTime.Now:HH:mm:ss} {line}";
lock (_lock)
{
if (_q.Count >= MaxLines) _q.Dequeue();
_q.Enqueue(msg);
// broadcast to live listeners (best effort, non-blocking)
foreach (var ch in _listeners.ToArray())
{
try { ch.Writer.TryWrite(msg); } catch { }
}
}
}
public static string[] Tail(int lines = 500)
{
if (lines < 1) lines = 1;
if (lines > MaxLines) lines = MaxLines;
lock (_lock)
{
var arr = _q.ToArray();
if (arr.Length <= lines) return arr;
var start = arr.Length - lines;
var result = new string[lines];
Array.Copy(arr, start, result, 0, lines);
return result;
}
}
// 👇 NEW: subscribe/unsubscribe for SSE
public static ChannelReader<string> Subscribe(out Channel<string> channel)
{
channel = Channel.CreateUnbounded<string>(new UnboundedChannelOptions
{
SingleReader = false,
SingleWriter = false
});
lock (_lock) { _listeners.Add(channel); }
return channel.Reader;
}
public static void Unsubscribe(Channel<string> channel)
{
lock (_lock) { _listeners.Remove(channel); }
try { channel.Writer.TryComplete(); } catch { }
}
}
}