Hangfire 1.6.19
.net core 2.1
Здравствуйте,
Когда я вызываю WebApi в повторяющемся задании, задание не выполняется из-за истечения времени ожидания вызова, поэтому я использую асинхронный метод для вызова, но при этом все задания выполняются успешно, и он не может отразить, успешно ли выполнен вызов WebApi. или не удается.
Так я судил по методу обратного вызова асинхронного запроса. Если WebApi возвращает исключение, статус задания изменяется как неудачный.
Однако из-за моей модификации список неудачных заданий Hangfire не работал должным образом. Предоставляет ли Hangfire внутренний метод для изменения статуса работы, или у вас есть какие-то лучшие решения?
Мой код выглядит следующим образом:
[AutomaticRetry(Attempts = 0)]
[DisplayName("InvokeApi,apiUrl:{0}")]
public void InvokeApi(string apiUrl, PerformContext context)
{
var invocationData = InvocationData.Serialize(context.BackgroundJob.Job);
int.TryParse(context?.BackgroundJob.Id, out var jobId);
var client = new RestClient(apiUrl)
{
Timeout = -1,
ReadWriteTimeout = -1
};
var request = new RestRequest(Method.GET)
{
Timeout = -1,
ReadWriteTimeout = -1
};
client.ExecuteAsync(request, response =>
{
if (!response.IsSuccessful)
{
using (var dbContext = new HangfireContext())
{
using (var transaction = dbContext.Database.BeginTransaction())
{
var state = dbContext.State.FirstOrDefault(x =>
x.JobId == jobId && x.Name == "Succeeded");
if (state != null)
{
state.Name = "Failed";
state.Reason = $"StatusDescription={response.StatusDescription},ErrorMessage={response.ErrorMessage ?? "null"}";
}
var job = dbContext.Job.FirstOrDefault(x => x.Id == jobId);
if (job != null)
{
job.StateName = "Failed";
job.InvocationData = Serialize(invocationData);
}
var counter =
dbContext.AggregatedCounter.FirstOrDefault(x => x.Key == "stats:succeeded");
if (counter != null) counter.Value = counter.Value - 1;
dbContext.SaveChanges();
transaction.Commit();
}
}
}
});
}
public string Serialize(InvocationData invocationData)
{
var parameterTypes = JobHelper.FromJson<string[]>(invocationData.ParameterTypes);
var arguments = JobHelper.FromJson<string[]>(invocationData.Arguments);
return JobHelper.ToJson(new MyJobPayload
{
TypeName = invocationData.Type,
MethodName = invocationData.Method,
ParameterTypes = parameterTypes != null && parameterTypes.Length > 0 ? parameterTypes : null,
Arguments = arguments != null && arguments.Length > 0 ? arguments : null
});
}
public class MyJobPayload
{
[JsonProperty("type")]
public string TypeName { get; set; }
[JsonProperty("m")]
public string MethodName { get; set; }
[JsonProperty("p", NullValueHandling = NullValueHandling.Ignore)]
public string[] ParameterTypes { get; set; }
[JsonProperty("a", NullValueHandling = NullValueHandling.Ignore)]
public string[] Arguments { get; set; }
}
С нетерпением жду вашего ответа, спасибо!