using MediatR; using Microsoft.Extensions.Logging; using ReC.Application.RecActions.Queries; namespace ReC.Application.RecActions.Commands; public record InvokeRecActionCommand : ReadRecActionQueryBase, IRequest; public static class InvokeRecActionCommandExtensions { public static Task InvokeRecAction(this ISender sender, int profileId) => sender.Send(new InvokeRecActionCommand { ProfileId = profileId }); } public class InvokeRecActionCommandHandler(ISender sender, IHttpClientFactory clientFactory, ILogger? logger = null) : IRequestHandler { public async Task Handle(InvokeRecActionCommand request, CancellationToken cancel) { var actions = await sender.Send(request.ToReadQuery(), cancel); var http = clientFactory.CreateClient(); using var semaphore = new SemaphoreSlim(5); var tasks = actions.Select(async action => { await semaphore.WaitAsync(cancel); try { if (action.RestType is null) { logger?.LogWarning( "Rec action could not be invoked because the RestType value is null. ProfileId: {ProfileId}, ActionId: {ActionId}", action.ProfileId, action.ActionId ); return; } var method = new HttpMethod(action.RestType.ToUpper()); var msg = new HttpRequestMessage(method, action.EndpointUri); var response = await http.SendAsync(msg, cancel); var body = await response.Content.ReadAsStringAsync(cancel); var headers = response.Headers.ToDictionary(); } catch(Exception ex) { logger?.LogError( ex, "Error invoking Rec action. ProfileId: {ProfileId}, ActionId: {ActionId}", action.ProfileId, action.ActionId ); } finally { semaphore.Release(); } }); await Task.WhenAll(tasks); } }