diff --git a/Program.cs b/Program.cs index 9d10e5b..3102c51 100644 --- a/Program.cs +++ b/Program.cs @@ -51,9 +51,9 @@ internal class Plat_integ { using var cmd = new OleDbCommand(query, connection); connection.Open(); - using var reader = cmd.ExecuteReader(); + using var reader = cmd.ExecuteReader(); - while (reader.Read()) + while (reader.Read()) { lista.Add( new perfil( @@ -72,6 +72,8 @@ internal class Plat_integ var limiter = new RateLimiter(400, TimeSpan.FromMinutes(1)); var errosPersistentes = new ConcurrentBag(); + var atualizados = new ConcurrentBag(); + var inseridos = new ConcurrentBag(); await using var dataSource = NpgsqlDataSource.Create(PG_CONN_STRING_PROD); @@ -125,28 +127,28 @@ internal class Plat_integ foreach (DateTime dia in datas) { - int tentativas = 0; - bool sucesso = false; + int tentativas = 0; + bool sucesso = false; - while (tentativas < 5 && !sucesso) - { + while (tentativas < 5 && !sucesso) + { if (perfil._Data_de_Migracao > dia) { Console.WriteLine($"Pular {perfil._Codigo_SCDE} - {dia.ToShortDateString()} (antes da migração)"); errosPersistentes.Add($"{perfil._Cod_5min};{perfil._Codigo_SCDE};Fora da data de migração {perfil._Data_de_Migracao} x {dia}"); break; // não tentar antes da data de migração } - try - { + try + { string payload = Xml_requisicao(dia, perfil._Cod_5min, perfil._Codigo_SCDE, 1); - var conteudo = new StringContent(payload, Encoding.UTF8, "application/xml"); + var conteudo = new StringContent(payload, Encoding.UTF8, "application/xml"); await limiter.WaitAsync(ct); - using var response = await client.PostAsync(endpoint, conteudo, ct); + using var response = await client.PostAsync(endpoint, conteudo, ct); string resposta = await response.Content.ReadAsStringAsync(); if ((int)response.StatusCode >= 400) - { + { try { VerificarRespostaSOAP(resposta); @@ -155,12 +157,12 @@ internal class Plat_integ { if (ex.ErrorCode == "2003") // limite de requisições { - var now = DateTime.UtcNow; - var delay = 60000 - (now.Second * 1000 + now.Millisecond); + var now = DateTime.UtcNow; + var delay = 60000 - (now.Second * 1000 + now.Millisecond); Console.WriteLine($"!! Limite de requisições atingido. Aguardando até {DateTime.Now.AddMilliseconds(delay)}"); await Task.Delay(delay, ct); // tentar de novo sem contar como falha continue; - } + } if (ex.ErrorCode == "4001") // Dados não encontrados { errosPersistentes.Add($"{perfil._Cod_5min};{perfil._Codigo_SCDE};SOAP Fault: {ex.ErrorCode};{ex.ErrorMessage.Replace("\n", "-n-")}"); @@ -180,24 +182,24 @@ internal class Plat_integ await ProcessarXMLAsync(resposta, dataSource, dia, perfil._Cod_5min, perfil._Codigo_SCDE, existentes, limiter, ct, 1); - sucesso = true; - } - catch (Exception ex) - { - tentativas++; - if (tentativas >= 5) - { - errosPersistentes.Add($"{perfil._Cod_5min};{perfil._Codigo_SCDE};Erro;{ex.Message.Replace("\n", "-n-")}"); + sucesso = true; } - else + catch (Exception ex) { - int backoff = (int)Math.Pow(2.4, tentativas) * 1000; // exponencial - Console.WriteLine($"Erro na requisição ({ex.Message}), tentativa {tentativas}. Aguardando {backoff / 1000}s..."); + tentativas++; + if (tentativas >= 5) + { + errosPersistentes.Add($"{perfil._Cod_5min};{perfil._Codigo_SCDE};Erro;{ex.Message.Replace("\n", "-n-")}"); + } + else + { + int backoff = (int)Math.Pow(2.4, tentativas) * 1000; // exponencial + Console.WriteLine($"Erro na requisição ({ex.Message}), tentativa {tentativas}. Aguardando {backoff / 1000}s..."); await Task.Delay(backoff); + } } } } - } Console.WriteLine($"{DateTime.Now}: Finalizado ponto {perfil._Codigo_SCDE}"); } catch (Exception ex) @@ -350,14 +352,14 @@ internal class Plat_integ foreach (var m in alterados) { var cmd = new NpgsqlBatchCommand(@" - UPDATE med_5min - SET origem = @origem, + UPDATE med_5min + SET origem = @origem, ativa_consumo = @ativa_consumo, ativa_geracao = @ativa_geracao, reativa_consumo = @reativa_consumo, reativa_geracao = @reativa_geracao - WHERE ponto = @ponto - AND dia_num = @dia_num + WHERE ponto = @ponto + AND dia_num = @dia_num AND minuto = @minuto;"); // Adiciona os parâmetros de forma segura @@ -382,7 +384,7 @@ internal class Plat_integ return; } public class SoapFaultException : Exception - { + { public string FaultCode { get; } public string FaultString { get; } public string ErrorCode { get; } @@ -406,7 +408,7 @@ internal class Plat_integ var fault = doc.Descendants(env + "Fault").FirstOrDefault(); if (fault != null) - { + { string faultCode = fault.Element("faultcode")?.Value ?? ""; string faultString = fault.Element("faultstring")?.Value ?? ""; @@ -416,7 +418,7 @@ internal class Plat_integ throw new SoapFaultException(faultCode, faultString, errorCode, message); } - } + } public class RateLimiter { @@ -427,7 +429,7 @@ internal class Plat_integ private readonly object _lock = new(); public RateLimiter(int maxRequests, TimeSpan interval) - { + { _maxRequests = maxRequests; _interval = interval; var now = DateTime.Now; @@ -458,9 +460,9 @@ internal class Plat_integ // já bateu o limite → espera até reset await Task.Delay(200, ct); // aguarda 200ms e tenta de novo } - } - } } + } +} public class perfil {