• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

luttje / Key2Joy / 6721644640

01 Nov 2023 03:26PM UTC coverage: 43.687% (-0.2%) from 43.884%
6721644640

push

github

luttje
add cheating warning

760 of 2407 branches covered (0.0%)

Branch coverage included in aggregate %.

3890 of 8237 relevant lines covered (47.23%)

12148.73 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

57.97
/Core/Key2Joy.Contracts/Plugins/Remoting/RemoteEventSubscriberClient.cs
1
using System;
2
using System.Diagnostics;
3
using System.IO;
4
using System.IO.Pipes;
5
using System.Threading;
6
using System.Threading.Tasks;
7

8
namespace Key2Joy.Contracts.Plugins.Remoting;
9

10
public class RemoteEventSubscriberClient
11
{
12
    public event EventHandler Disposing;
13

14
    private readonly NamedPipeClientStream pipeStream;
15

16
    private DateTime lastHeartbeatAt = DateTime.Now;
14✔
17
    private CancellationTokenSource pipeCancellation;
18

19
    internal RemoteEventSubscriberClient(string portName)
14✔
20
    {
21
        this.pipeStream = new NamedPipeClientStream(
14✔
22
            ".",
14✔
23
            RemotePipe.GetClientPipeName(portName),
14✔
24
            PipeDirection.InOut,
14✔
25
            PipeOptions.Asynchronous);
14✔
26
        this.pipeStream.Connect();
14✔
27
        this.pipeStream.ReadMode = PipeTransmissionMode.Message;
14✔
28

29
        this.pipeCancellation = new CancellationTokenSource();
14✔
30

31
        this.InitBackgroundHeartbeatThread();
14✔
32
    }
14✔
33

34
    /// <summary>
35
    /// Called from the client to send a message to the host.
36
    /// </summary>
37
    /// <param name="message"></param>
38
    /// <exception cref="IOException"></exception>
39
    internal void SendToHost(string message) => RemotePipe.WriteMessage(this.pipeStream, message);
14✔
40

41
    public void AskHostToInvokeSubscription(RemoteEventArgs e) => this.SendToHost(e.Subscription.Id.ToString());
×
42

43
    /// <summary>
44
    /// Checks in the background if the host has shown any sign of life recently.
45
    /// </summary>
46
    private void InitBackgroundHeartbeatThread()
47
    {
48
        // Registers heartbeats from the host.
49
        var pipeListenerBackgroundThread = Task.Run(() =>
14✔
50
        {
14✔
51
            try
14✔
52
            {
14✔
53
                while (!this.pipeCancellation.IsCancellationRequested)
5,600,183✔
54
                {
14✔
55
                    var message = RemotePipe.ReadMessage(this.pipeStream);
5,600,183✔
56

14✔
57
                    if (string.IsNullOrEmpty(message))
5,600,169✔
58
                    {
14✔
59
                        continue;
14✔
60
                    }
14✔
61

14✔
62
                    Console.WriteLine($"Remote Message: {message}");
×
63
                    this.lastHeartbeatAt = DateTime.Now;
×
64
                }
14✔
65
            }
×
66
            catch (ObjectDisposedException) { } // in case pipe closed
×
67
        });
14✔
68

69
        // Checks if the last heartbeat was too long ago.
70
        var pipeCancellerBackgroundThread = Task.Run(() =>
14✔
71
        {
14✔
72
            while (!this.pipeCancellation.IsCancellationRequested)
43✔
73
            {
14✔
74
                if (DateTime.Now - this.lastHeartbeatAt > RemoteEventSubscriber.MaxHeartbeatInterval)
43✔
75
                {
14✔
76
                    Console.WriteLine("Host is not responding. Shutting down.");
×
77
                    this.Dispose();
×
78
                    return;
×
79
                }
14✔
80

14✔
81
                Thread.Sleep(1000);
43✔
82
            }
14✔
83
        });
14✔
84
    }
14✔
85

86
    public void Exit()
87
    {
88
        if (!this.pipeStream.IsConnected)
×
89
        {
90
            return;
×
91
        }
92

93
        try
94
        {
95
            this.SendToHost(RemoteEventSubscriber.SignalExit);
×
96
        }
×
97
        catch (IOException ex)
×
98
        {
99
            Output.WriteLine(ex);
×
100
            Debug.WriteLine(ex);
101
        }
×
102

103
        this.Dispose();
×
104
    }
×
105

106
    public void Dispose()
107
    {
108
        this.Disposing?.Invoke(this, EventArgs.Empty);
×
109

110
        this.pipeStream?.Dispose();
×
111

112
        this.pipeCancellation?.Cancel();
×
113
    }
×
114
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc