private static void ProcessPulses(object sender, ElapsedEventArgs e) { Task.Run(() => { try { if (pulseQueue != null && ((currentPulse != null && !currentPulse.isEmpty()) || !pulseQueue.IsEmpty) && EnoughTimePassed(DateTime.Now)) { if (currentPulse != null && !currentPulse.isEmpty()) { pulseQueue.Enqueue(currentPulse); currentPulse = new Pulse(); currentCount = 0; } // run only if the task didn't run yet, or the previous one already finished if (pulseProcessor == null || pulseProcessor.IsCompleted || pulseProcessor.IsFaulted) // don't start if it's cancelled { try { pulseProcessor = ProcessPulses(pulseProcessor_tokensource); } catch (OperationCanceledException) {} } //ProcessPulses(); } UpdateStatusbar(); } catch (Exception ex) { Logger.Error("Error processing pulses", ex); } }); }
private static void ProcessPulses() { if (pulseQueue != null && ((currentPulse != null && !currentPulse.isEmpty()) || !pulseQueue.IsEmpty) && EnoughTimePassed(DateTime.Now)) { if (currentPulse != null && !currentPulse.isEmpty()) { pulseQueue.Enqueue(currentPulse); currentPulse = new Pulse(); currentCount = 0; } if (String.IsNullOrWhiteSpace(ApiKey)) { Logger.Debug("No API token - cannot pulse!"); return; } var client = new WebClient { Proxy = CodeStatsPackage.GetProxy() }; var jsonSerializer = new JavaScriptSerializer(); string URL; if (String.IsNullOrWhiteSpace(_CodeStatsConfigFile.ApiUrl)) { URL = Constants.ApiMyPulsesEndpoint; } else { URL = _CodeStatsConfigFile.ApiUrl; } client.Headers[HttpRequestHeader.UserAgent] = Constants.PluginUserAgent; client.Headers[HttpRequestHeader.ContentType] = "application/json"; client.Headers[HttpRequestHeader.Accept] = "*/*"; client.Headers["X-API-Token"] = ApiKey; Pulse result; while (pulseQueue.TryDequeue(out result)) { if (!result.isEmpty()) { bool error = false; // Try to pulse to API try { string json = jsonSerializer.Serialize(result); Logger.Debug("Pulsing " + json); string HtmlResult = client.UploadString(URL, json); _lastPulse = DateTime.Now; if (!HtmlResult.Contains(@"""ok""") && !HtmlResult.Contains(@"success")) { error = true; Logger.Error(@"Error pulsing, response does not contain ""ok"" or ""success"": " + HtmlResult); } } catch (WebException ex) { error = true; if (ex.Status == WebExceptionStatus.ProtocolError) { var response = ex.Response as HttpWebResponse; if (response != null && (int)response.StatusCode == 403) { if (!_shownInvalidApiTokenMessage) // we want to inform user only once, and if he does not provide the token, let's not bomb him with error each time after he types something { MessageBox.Show("Could not pulse. Please make sure you entered a valid API token in Code::Stats settings.", "Code::Stats - error 403", MessageBoxButtons.OK, MessageBoxIcon.Error); _shownInvalidApiTokenMessage = true; } Logger.Error("Could not pulse. Please make sure you entered a valid API token in Code::Stats settings.", ex); } else { // response==null - no http status code available Logger.Error("Could not pulse. Are you behind a proxy? Try setting a proxy in Code::Stats settings with format https://user:pass@host:port. Exception Traceback", ex); } } else { Logger.Error("Could not pulse. Are you behind a proxy? Try setting a proxy in Code::Stats settings with format https://user:pass@host:port. Exception Traceback", ex); } } catch (Exception ex) { error = true; Logger.Error("Error pulsing. Exception Traceback", ex); } if (error) { pulseQueue.Enqueue(result); // Requeue, since we failed to pulse return; } } } } UpdateStatusbar(); }