From 475950be36220b59103db44ac0e19a8f4a73802a Mon Sep 17 00:00:00 2001 From: kjh2064 Date: Sun, 12 Jul 2026 13:36:52 +0900 Subject: [PATCH] feat(web): add manual trigger action support for Hangfire recurring jobs --- .../Pages/Admin/Operations/Index.cshtml | 19 ++++++++++++- .../Pages/Admin/Operations/Index.cshtml.cs | 27 ++++++++++++++++++- 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/dotnet/QuantEngine.Web/Pages/Admin/Operations/Index.cshtml b/src/dotnet/QuantEngine.Web/Pages/Admin/Operations/Index.cshtml index 3730891d..497c7560 100644 --- a/src/dotnet/QuantEngine.Web/Pages/Admin/Operations/Index.cshtml +++ b/src/dotnet/QuantEngine.Web/Pages/Admin/Operations/Index.cshtml @@ -16,6 +16,18 @@
+ @if (TempData["SuccessMessage"] != null) + { + + } + @if (TempData["ErrorMessage"] != null) + { + + }
@@ -56,7 +68,12 @@ } - 수정 +
+ @Html.AntiForgeryToken() + + +
+ 수정 } diff --git a/src/dotnet/QuantEngine.Web/Pages/Admin/Operations/Index.cshtml.cs b/src/dotnet/QuantEngine.Web/Pages/Admin/Operations/Index.cshtml.cs index 50ef1263..12f3a606 100644 --- a/src/dotnet/QuantEngine.Web/Pages/Admin/Operations/Index.cshtml.cs +++ b/src/dotnet/QuantEngine.Web/Pages/Admin/Operations/Index.cshtml.cs @@ -1,6 +1,7 @@ using Hangfire; using Hangfire.Storage; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; using QuantEngine.Web.Services; @@ -32,6 +33,29 @@ public class IndexModel : PageModel return Task.CompletedTask; } + public async Task OnPostTriggerJobAsync(string jobId) + { + if (string.IsNullOrEmpty(jobId)) + { + TempData["ErrorMessage"] = "올바르지 않은 작업 ID입니다."; + return RedirectToPage(); + } + + try + { + RecurringJob.TriggerJob(jobId); + TempData["SuccessMessage"] = $"작업 '{DescribeJobId(jobId)}'이(가) 즉시 실행 큐에 등록되었습니다."; + _logger.LogInformation("Manually triggered Hangfire recurring job: {JobId}", jobId); + } + catch (Exception ex) + { + _logger.LogError(ex, "Failed to trigger Hangfire job: {JobId}", jobId); + TempData["ErrorMessage"] = $"작업 실행 실패: {ex.Message}"; + } + + return RedirectToPage(); + } + private void LoadOperationsData() { try @@ -51,6 +75,7 @@ public class IndexModel : PageModel var recurringJobs = connection.GetRecurringJobs(); ScheduledJobs = recurringJobs .Select(j => new ScheduledJobInfo( + j.Id, DescribeJobId(j.Id), DescribeCron(j.Cron), j.NextExecution, @@ -127,5 +152,5 @@ public class IndexModel : PageModel }; } -public record ScheduledJobInfo(string JobName, string Schedule, DateTime? NextRun, bool IsEnabled); +public record ScheduledJobInfo(string JobId, string JobName, string Schedule, DateTime? NextRun, bool IsEnabled); public record JobExecutionInfo(string JobName, DateTime StartedAt, DateTime? CompletedAt, bool IsSuccess);