# Queueing

Miru has some Queueing facilities on top of Hangfire.

# Create a Job

To create a Job, a Maker from MiruCli can be used:

miru make:job Accounts Account Created

# Job

A Job is composed by the Request and the Handler. It is a class named after the job being done (e.g. OrderPlaced, UserCreated, and ImageAttached). Request and Handler stay inside as subclasses:

    public class OrderPaid
    {
        public class Request : IJob
        {
        }
        
        public class Handler : IRequestHandler<Request>
        {
            public Task<Unit> Handle(Request request, CancellationToken cancellationToken)
            {
                return Unit.Task;
            }
        }
    }

The class's file can be placed in the Feature's folder. Examples:

/src/App/Features/Orders/OrderPaid.cs
/src/App/Features/Users/UserCreated.cs

# Request

The Job's Request holds the input data that will be used by the Handler when the job is processed. It is a class that implements IJob.

        public class Request : IJob
        {
            public long OrderId { get; set; }
        }

# Handler

A Job's Handler will be called when the queue scheduler execute the job. It is a class that implements IRequestHandler.

        public class Handler : IRequestHandler<Request>
        {
            public async Task<Unit> Handle(Request request, CancellationToken ct)
            {
                var orderId = request.OrderId;
                
                // do something
                
                return await Unit.Task;
            }
        }

# Queueing Jobs

Queueing jobs are done through Jobs class:

_jobs.PerformLater(job);
public class Handler : IRequestHandler<Request, Order>
{
    private readonly Jobs _jobs;

    public Handler(Jobs jobs)
    {
        _jobs = jobs;
    }

    public async Task<Order> Handle(Request request, CancellationToken cancellationToken)
    {
        var order = new Order();
        
        // place order logic
        
        _jobs.PerformLater(new OrderPlaced.Request
        {
            OrderId = order.Id
        });
        
        return order;
    }
}

# Processing Queued Jobs

The queued jobs are processed by Hangfire's BackgroundJobServer. There are two ways of start the server and keep it running: together with the WebApp or standalone.

# Server with WebApp

In src/App/Startup.cs ConfigureService method, add AddHangfireServer:

                // queuing
                .AddQueuing(_ => 
                {
                    _.UseLiteDb();
                })
                .AddHangfireServer()

# Server Standalone

Can be started invoking:

miru queue:run

WARNING

Pay attention to not run the BackgroundJobServer in both ways at the same time.

# Dashboard

Dashboard can be enabled in src/App/Startup.cs middleware configuration:

            app.UseRouting();
            app.UseAuthentication();
            app.UseQueueAdminDashboard<User>();
            
            app.UseEndpoints(e =>
            {
                e.MapDefaultControllerRoute();
            });

It will use Userfy authorization to allow only Admin access the Dashboard. The default url route is /_queue.

Configurations can be customized using Hangfire's API.