본문 바로가기
카테고리 없음

주석

by keisoft 2025. 2. 12.

아래는 코드의 주요 부분에 대한 설명을 포함한 주석을 추가한 버전입니다.


---

1. Shared Models (Shared.Models 프로젝트)

public class WorkRequest
{
    public string ActionType { get; set; }  // "Sync" (동기) 또는 "Async" (비동기)
    public string Data { get; set; }  // 작업에 필요한 데이터
    public Dictionary<string, string> Parameters { get; set; } // 추가적인 파라미터들
    public DateTime RequestTime { get; set; } = DateTime.UtcNow; // 요청 생성 시간
}

public class WorkResponse
{
    public bool Success { get; set; }  // 작업 성공 여부
    public string Result { get; set; }  // 작업 결과
    public string ErrorMessage { get; set; } // 오류 메시지 (실패 시)
    public DateTime ResponseTime { get; set; } // 응답 시간
}

public enum WorkPriority
{
    Low = 0,    // 낮은 우선순위
    Normal = 1, // 일반 우선순위
    High = 2    // 높은 우선순위
}


---

2. Blazor SSR Client (BlazorApp.Client 프로젝트)

IWorkerManagerService (인터페이스)

public interface IWorkerManagerService
{
    Task<WorkResponse> ProcessRequestAsync(WorkRequest request, WorkPriority priority = WorkPriority.Normal);
    Task<WorkerManagerStatus> GetStatusAsync();
}

ProcessRequestAsync : 작업 요청을 서버로 전송하고 결과를 반환

GetStatusAsync : 현재 작업 매니저의 상태를 조회


WorkerManagerService (서비스 구현)

public class WorkerManagerService : IWorkerManagerService
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<WorkerManagerService> _logger;

    public WorkerManagerService(HttpClient httpClient, ILogger<WorkerManagerService> logger)
    {
        _httpClient = httpClient;
        _logger = logger;
    }

    public async Task<WorkResponse> ProcessRequestAsync(WorkRequest request, WorkPriority priority = WorkPriority.Normal)
    {
        try
        {
            var response = await _httpClient.PostAsJsonAsync("api/workermanager/process", new { Request = request, Priority = priority });
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadFromJsonAsync<WorkResponse>();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error processing request");
            throw;
        }
    }

    public async Task<WorkerManagerStatus> GetStatusAsync()
    {
        try
        {
            var response = await _httpClient.GetAsync("api/workermanager/status");
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadFromJsonAsync<WorkerManagerStatus>();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error getting status");
            throw;
        }
    }
}

서버의 API 엔드포인트와 통신하여 작업 요청을 처리

현재 작업 매니저의 상태를 조회


Blazor 모니터링 페이지

@page "/monitor"
@inject IWorkerManagerService WorkerManagerService
@implements IDisposable

WorkerManagerService를 주입하여 작업 상태를 조회

IDisposable을 구현하여 Timer 해제


@code {
    private WorkerManagerStatus status;
    private Timer timer;

    protected override void OnInitialized()
    {
        // 주기적으로 상태 업데이트
        timer = new Timer(async _ =>
        {
            status = await WorkerManagerService.GetStatusAsync();
            await InvokeAsync(StateHasChanged);
        }, null, 0, 1000);
    }

    public void Dispose()
    {
        timer?.Dispose();
    }
}

매 초마다 서버로부터 상태를 받아와 UI를 갱신

Dispose에서 타이머 해제



---

3. Worker Manager (WorkerManager.API 프로젝트)

WorkerManagerController

[ApiController]
[Route("api/[controller]")]
public class WorkerManagerController : ControllerBase
{
    private readonly IWorkerManagerService _workerManagerService;

    public WorkerManagerController(IWorkerManagerService workerManagerService)
    {
        _workerManagerService = workerManagerService;
    }

    [HttpPost("process")]
    public async Task<IActionResult> ProcessRequest([FromBody] WorkRequest request)
    {
        var result = await _workerManagerService.ProcessRequestAsync(request);
        return Ok(result);
    }

    [HttpGet("status")]
    public async Task<IActionResult> GetStatus()
    {
        var status = await _workerManagerService.GetStatusAsync();
        return Ok(status);
    }
}

작업 요청을 WorkerManagerService에 전달

현재 작업 상태를 조회하는 API 제공


WorkerManagerService

private async Task ProcessQueueAsync()
{
    while (_workQueue.TryDequeue(out var work))
    {
        await _workerSemaphore.WaitAsync();
        _ = ProcessWorkItemAsync(work);
    }
}

작업 큐를 처리하는 백그라운드 작업 실행



---

4. Worker Client (WorkerManager.Infrastructure 프로젝트)

WorkerClient

public class WorkerClient : IWorkerClient
{
    private readonly HttpClient _httpClient;
    private readonly ILogger<WorkerClient> _logger;

    public WorkerClient(HttpClient httpClient, ILogger<WorkerClient> logger)
    {
        _httpClient = httpClient;
        _logger = logger;
    }

    public async Task<WorkResponse> ProcessAsync(WorkRequest request)
    {
        try
        {
            var response = await _httpClient.PostAsJsonAsync("api/worker/process", request);
            response.EnsureSuccessStatusCode();
            return await response.Content.ReadFromJsonAsync<WorkResponse>();
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Error processing request");
            throw;
        }
    }
}

Worker API와 통신하여 실제 작업을 처리



---

5. Worker API (Worker.API 프로젝트)

WorkerController

[HttpPost("process")]
public async Task<IActionResult> Process([FromBody] WorkRequest request)
{
    try
    {
        if (request.ActionType == "Async")
        {
            await _taskQueue.QueueBackgroundWorkItemAsync(async token =>
            {
                await _customActionService.ExecuteActionAsync(request.Data);
            });

            return Ok(new WorkResponse
            {
                Success = true,
                Result = "작업이 백그라운드에서 실행됩니다.",
                ResponseTime = DateTime.UtcNow
            });
        }
        
        var result = await _customActionService.ExecuteActionAsync(request.Data);
        return Ok(new WorkResponse
        {
            Success = true,
            Result = result,
            ResponseTime = DateTime.UtcNow
        });
    }
    catch (Exception ex)
    {
        _logger.LogError(ex, "Error processing request");
        return StatusCode(500, new WorkResponse
        {
            Success = false,
            ErrorMessage = ex.Message,
            ResponseTime = DateTime.UtcNow
        });
    }
}

동기/비동기 작업을 실행

비동기 작업은 백그라운드 큐에서 실행



---

요약

이 프로젝트는 작업 요청을 처리하는 시스템을 구현한 것입니다.

1. Blazor 클라이언트에서 작업 요청을 보냄


2. Worker Manager API가 요청을 받아 적절한 큐에 할당


3. Worker Client가 Worker API와 통신하여 실제 작업을 처리


4. Worker API가 작업을 수행하고 응답 반환


5. Blazor 모니터링 페이지에서 진행 중인 작업 상태를 확인



이해가 쉬워지도록 코드마다 주요 개념을 주석으로 설명했습니다!