Projekt

Obecné

Profil

« Předchozí | Další » 

Revize e6a01bd8

Přidáno uživatelem Pultak před asi 2 roky(ů)

re #9712 Added documentation of the newly implemented methods + refactoring

Zobrazit rozdíly:

ld_client/LDClient/detection/ProcessDetection.cs
1
using System.Diagnostics;
2
using LDClient.network;
1
using LDClient.network;
3 2
using LDClient.network.data;
4 3

  
5
namespace LDClient.detection {
4
namespace LDClient.detection; 
5

  
6
/// <summary>
7
/// This class takes care of process detection. When t32mtc (process)
8
/// is detected, it means that the debugger is currently being used.
9
/// The class keeps track of the current state of a debugger.
10
/// </summary>
11
public sealed class ProcessDetection : IProcessDetection {
6 12

  
7 13
    /// <summary>
8
    /// This class takes care of process detection. When t32mtc (process)
9
    /// is detected, it means that the debugger is currently being used.
10
    /// The class keeps track of the current state of a debugger.
14
    /// Datetime format used when sending payloads to the server.
11 15
    /// </summary>
12
    public sealed class ProcessDetection : IProcessDetection {
13

  
14
        /// <summary>
15
        /// Datetime format used when sending payloads to the server.
16
        /// </summary>
17
        private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";
16
    private const string DatetimeFormat = "yyyy-MM-dd hh:mm:ss";
18 17

  
19
        /// <summary>
20
        /// Name of the process the application detects.
21
        /// </summary>
22
        private readonly string _processName;
18
    /// <summary>
19
    /// Name of the process the application detects.
20
    /// </summary>
21
    private readonly string _processName;
23 22
        
24
        /// <summary>
25
        /// How often the application check the current status of the process (cunning / not running).
26
        /// </summary>
27
        private readonly uint _detectionPeriodMs;
23
    /// <summary>
24
    /// How often the application check the current status of the process (cunning / not running).
25
    /// </summary>
26
    private readonly uint _detectionPeriodMs;
28 27
        
29
        /// <summary>
30
        /// Instance of InfoFetcher used to fetch information from the debugger
31
        /// (when the process is detected).
32
        /// </summary>
33
        private readonly IInfoFetcher _infoFetcher;
28
    /// <summary>
29
    /// Instance of InfoFetcher used to fetch information from the debugger
30
    /// (when the process is detected).
31
    /// </summary>
32
    private readonly IInfoFetcher _infoFetcher;
34 33
        
35
        /// <summary>
36
        /// Instance of API clients used for sending data off to the server.
37
        /// </summary>
38
        private readonly IApiClient _apiClient;
34
    /// <summary>
35
    /// Instance of API clients used for sending data off to the server.
36
    /// </summary>
37
    private readonly IApiClient _apiClient;
39 38
        
40
        /// <summary>
41
        /// Instance of ProcessUtils which encapsulates common functionality
42
        /// when it comes to dealing with processes (limited by the needs of this application).
43
        /// </summary>
44
        private readonly IProcessUtils _processUtils;
39
    /// <summary>
40
    /// Instance of ProcessUtils which encapsulates common functionality
41
    /// when it comes to dealing with processes (limited by the needs of this application).
42
    /// </summary>
43
    private readonly IProcessUtils _processUtils;
45 44

  
46
        /// <summary>
47
        /// Flag indicating whether the process is currently running or not.
48
        /// </summary>
49
        private bool _processIsActive;
45
    /// <summary>
46
    /// Flag indicating whether the process is currently running or not.
47
    /// </summary>
48
    private bool _processIsActive;
50 49
        
51
        /// <summary>
52
        /// Flag if the application failed to retrieve data when the process was detected.
53
        /// </summary>
54
        private bool _failedToRetrieveData;
50
    /// <summary>
51
    /// Flag if the application failed to retrieve data when the process was detected.
52
    /// </summary>
53
    private bool _failedToRetrieveData;
55 54
        
56
        /// <summary>
57
        /// Last payload that was sent to the server.
58
        /// </summary>
59
        private Payload? _lastConnectedPayload;
55
    /// <summary>
56
    /// Last payload that was sent to the server.
57
    /// </summary>
58
    private Payload? _lastConnectedPayload;
60 59

  
61
        /// <summary>
62
        /// Flag used to stop the thread (process detection).
63
        /// </summary>
64
        public bool DetectionRunning = false;
60
    /// <summary>
61
    /// Flag used to stop the thread (process detection).
62
    /// </summary>
63
    public bool DetectionRunning = false;
65 64
        
66
        /// <summary>
67
        /// Creates an instance of this class.
68
        /// </summary>
69
        /// <param name="processName">Name of the process the application detects</param>
70
        /// <param name="detectionPeriodMs">How often the application check the current status of the process (cunning / not running)</param>
71
        /// <param name="infoFetcher">Instance of InfoFetcher used to fetch information from the debugger</param>
72
        /// <param name="apiClient">Instance of API clients used for sending data off to the server</param>
73
        /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param>
74
        public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher,
75
            IApiClient apiClient, IProcessUtils processUtils) {
76
            _processName = processName;
77
            _detectionPeriodMs = detectionPeriodMs;
78
            _infoFetcher = infoFetcher;
79
            _apiClient = apiClient;
80
            _failedToRetrieveData = false;
81
            _processUtils = processUtils;
82
        }
65
    /// <summary>
66
    /// Creates an instance of this class.
67
    /// </summary>
68
    /// <param name="processName">Name of the process the application detects</param>
69
    /// <param name="detectionPeriodMs">How often the application check the current status of the process (cunning / not running)</param>
70
    /// <param name="infoFetcher">Instance of InfoFetcher used to fetch information from the debugger</param>
71
    /// <param name="apiClient">Instance of API clients used for sending data off to the server</param>
72
    /// <param name="processUtils">Instance of ProcessUtils which encapsulates common functionality when it comes to dealing with processes (limited by the needs of this application)</param>
73
    public ProcessDetection(string processName, uint detectionPeriodMs, IInfoFetcher infoFetcher,
74
        IApiClient apiClient, IProcessUtils processUtils) {
75
        _processName = processName;
76
        _detectionPeriodMs = detectionPeriodMs;
77
        _infoFetcher = infoFetcher;
78
        _apiClient = apiClient;
79
        _failedToRetrieveData = false;
80
        _processUtils = processUtils;
81
    }
83 82

  
84
        /// <summary>
85
        /// Retrieves data from the debugger.
86
        /// </summary>
87
        /// <returns>True, if the data was fetched successfully. False, otherwise.</returns>
88
        private async Task<bool> RetrieveDataFromDebugger() {
89
            // Try to fetch data from the debugger.
90
            var success = await _infoFetcher.FetchDataAsync();
83
    /// <summary>
84
    /// Retrieves data from the debugger.
85
    /// </summary>
86
    /// <returns>True, if the data was fetched successfully. False, otherwise.</returns>
87
    private async Task<bool> RetrieveDataFromDebugger() {
88
        // Try to fetch data from the debugger.
89
        var success = await _infoFetcher.FetchDataAsync();
91 90
            
92
            // If the data was fetched successfully, send a payload off to the server.
93
            if (success) {
94
                _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber,
95
                    _infoFetcher.BodySerialNumber, DatetimeFormat);
96
            }
97
            return success;
91
        // If the data was fetched successfully, send a payload off to the server.
92
        if (success) {
93
            _lastConnectedPayload = await SendDataToServerAsync(_infoFetcher.HeadSerialNumber,
94
                _infoFetcher.BodySerialNumber, DatetimeFormat);
98 95
        }
96
        return success;
97
    }
99 98

  
100
        /// <summary>
101
        /// Sends a payload to the server when a debugger gets disconnected.
102
        /// </summary>
103
        private async Task DebuggerDisconnected() {
104
            // Make sure the debugger was connected in the first place.
105
            if (_lastConnectedPayload is not null) {
106
                // Update the status and timestamp of the last payload
107
                // (the serial numbers remain the same).
108
                _lastConnectedPayload.Status = ConnectionStatus.Disconnected;
109
                _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat);
99
    /// <summary>
100
    /// Sends a payload to the server when a debugger gets disconnected.
101
    /// </summary>
102
    private async Task DebuggerDisconnected() {
103
        // Make sure the debugger was connected in the first place.
104
        if (_lastConnectedPayload is not null) {
105
            // Update the status and timestamp of the last payload
106
            // (the serial numbers remain the same).
107
            _lastConnectedPayload.Status = ConnectionStatus.Disconnected;
108
            _lastConnectedPayload.TimeStamp = DateTime.Now.ToString(DatetimeFormat);
110 109
                
111
                // Send the data to the server.
112
                await _apiClient.SendPayloadAsync(_lastConnectedPayload);
110
            // Send the data to the server.
111
            await _apiClient.SendPayloadAsync(_lastConnectedPayload);
113 112
                
114
                // Clear the last payload.
115
                _lastConnectedPayload = null;
116
            }
113
            // Clear the last payload.
114
            _lastConnectedPayload = null;
117 115
        }
116
    }
118 117

  
119
        /// <summary>
120
        /// Checks if the t32mtc process is running or not. 
121
        /// </summary>
122
        private async Task DetectProcessAsync() {
123
            // Check if the process is running.
124
            var processExists = _processUtils.IsProcessRunning(_processName);
118
    /// <summary>
119
    /// Checks if the t32mtc process is running or not. 
120
    /// </summary>
121
    private async Task DetectProcessAsync() {
122
        // Check if the process is running.
123
        var processExists = _processUtils.IsProcessRunning(_processName);
125 124

  
126
            // Check if the process was not running but now it is (flip flop ON). 
127
            if (processExists && !_processIsActive) {
128
                Program.DefaultLogger.Info($"Process started: {_processName}");
129
                if (!_failedToRetrieveData) {
130
                    _failedToRetrieveData = !await RetrieveDataFromDebugger();
131
                }
132
            }
133
            // Check if the process was running but now it is not (fli flop OFF).
134
            else if (!processExists && _processIsActive) {
135
                Program.DefaultLogger.Info($"Process stopped: {_processName}");
136
                _failedToRetrieveData = false;
137
                await DebuggerDisconnected();
125
        // Check if the process was not running but now it is (flip flop ON). 
126
        if (processExists && !_processIsActive) {
127
            Program.DefaultLogger.Info($"Process started: {_processName}");
128
            if (!_failedToRetrieveData) {
129
                _failedToRetrieveData = !await RetrieveDataFromDebugger();
138 130
            }
139

  
140
            // Keep track of the current state of the debugger.
141
            _processIsActive = processExists;
131
        }
132
        // Check if the process was running but now it is not (fli flop OFF).
133
        else if (!processExists && _processIsActive) {
134
            Program.DefaultLogger.Info($"Process stopped: {_processName}");
135
            _failedToRetrieveData = false;
136
            await DebuggerDisconnected();
142 137
        }
143 138

  
144
        /// <summary>
145
        /// Creates a payload and sends it to the server.
146
        /// </summary>
147
        /// <param name="headSerialNumber">serial number of the head of the debugger</param>
148
        /// <param name="bodySerialNumber">serial number of the body of the debugger</param>
149
        /// <param name="datetimeFormat">datetime format (timestamp)</param>
150
        /// <returns>the newly-created payload</returns>
151
        private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) {
152
            // Create a new payload. 
153
            Payload payload = new() {
154
                UserName = Environment.UserName,
155
                HostName = Environment.MachineName,
156
                TimeStamp = DateTime.Now.ToString(datetimeFormat),
157
                HeadDevice = new DebuggerInfo {
158
                    SerialNumber = headSerialNumber
159
                },
160
                BodyDevice = new DebuggerInfo {
161
                    SerialNumber = bodySerialNumber
162
                },
163
                Status = ConnectionStatus.Connected
164
            };
139
        // Keep track of the current state of the debugger.
140
        _processIsActive = processExists;
141
    }
142

  
143
    /// <summary>
144
    /// Creates a payload and sends it to the server.
145
    /// </summary>
146
    /// <param name="headSerialNumber">serial number of the head of the debugger</param>
147
    /// <param name="bodySerialNumber">serial number of the body of the debugger</param>
148
    /// <param name="datetimeFormat">datetime format (timestamp)</param>
149
    /// <returns>the newly-created payload</returns>
150
    private async Task<Payload> SendDataToServerAsync(string headSerialNumber, string bodySerialNumber, string datetimeFormat) {
151
        // Create a new payload. 
152
        Payload payload = new() {
153
            UserName = Environment.UserName,
154
            HostName = Environment.MachineName,
155
            TimeStamp = DateTime.Now.ToString(datetimeFormat),
156
            HeadDevice = new DebuggerInfo {
157
                SerialNumber = headSerialNumber
158
            },
159
            BodyDevice = new DebuggerInfo {
160
                SerialNumber = bodySerialNumber
161
            },
162
            Status = ConnectionStatus.Connected
163
        };
165 164
            
166
            // Send it to the server and return it.
167
            await _apiClient.SendPayloadAsync(payload);
168
            return payload;
169
        }
165
        // Send it to the server and return it.
166
        await _apiClient.SendPayloadAsync(payload);
167
        return payload;
168
    }
170 169

  
171
        /// <summary>
172
        /// Periodically runs process detection. This method is instantiated
173
        /// as a thread from the main class (Program.cs).
174
        /// </summary>
175
        public async void RunPeriodicDetection() {
176
            Program.DefaultLogger.Info("Process periodic detector has started");
177
            DetectionRunning = true;
170
    /// <summary>
171
    /// Periodically runs process detection. This method is instantiated
172
    /// as a thread from the main class (Program.cs).
173
    /// </summary>
174
    public async void RunPeriodicDetection() {
175
        Program.DefaultLogger.Info("Process periodic detector has started");
176
        DetectionRunning = true;
178 177
            
179
            while (DetectionRunning) {
180
                await DetectProcessAsync();
181
                Thread.Sleep((int) _detectionPeriodMs);
182
            }
178
        while (DetectionRunning) {
179
            await DetectProcessAsync();
180
            Thread.Sleep((int) _detectionPeriodMs);
183 181
        }
184 182
    }
185
}
183
}

Také k dispozici: Unified diff