简体   繁体   中英

How to cancel long running task in MassTransit

I am using the following example as a refernce point to create deploy MassTransit. My goal is to simulate Recovery (It works for that) Scaling (Also works) Canceling (Unable to make it work and need help around that) Continues responses/progress (progress of the job - probably my next task)

(More description as i was put on hold thanks for guiding me guys) These are the nuget packages needed

MassTransit MassTransit.RabbitMQ RabbitMQ.Client TopShelf

So this is the producer that i have. It just takes a string to trigger a job and get the response from that job.

internal class Program
    {
        private static void Main()
        {
            IBusControl busControl = CreateBus();
            busControl.Start();
            try
            {
                for (; ; )
                {
                    Console.Write("Message to process (quit exits): ");
                    string customerId = Console.ReadLine();
                    if (customerId == "quit")
                        break;

                var serviceAddress = new Uri("rabbitmq://localhost/request_service");
                IRequestClient<ISimpleRequest, ISimpleResponse> c2 =
                    busControl.CreateRequestClient<ISimpleRequest, ISimpleResponse>(serviceAddress, TimeSpan.FromDays(10));
                Task.Run(async () =>
                {
                    ISimpleResponse response = await c2.Request(new SimpleRequest(customerId));

                    Console.WriteLine("Processing of message {0} is successful", response.CusomerName);
                });
            }
        }
        catch (Exception ex)
        {Console.WriteLine("Exception!!! OMG!!! {0}", ex);}
        finally
        {
            busControl.Stop();
        }
    }

    private static IBusControl CreateBus()
    {
        return Bus.Factory.CreateUsingRabbitMq(x => x.Host(new Uri("rabbitmq://localhost"), h =>
        {
            h.Username("guest");
            h.Password("guest");
        }));
    }
}

Below is the code for consumer. The consumer just picks up a message and have a Thread of 30 sec to simulate long running jobs.

    class Program
    {
        static int Main(string[] args)
        {
            return (int)HostFactory.Run(x => x.Service());
        }
    }

public class InitiateServiceBus : ServiceControl { IBusControl _busControl; public bool Start(HostControl hostControl) { _busControl = Bus.Factory.CreateUsingRabbitMq(x => { IRabbitMqHost host = x.Host(new Uri("rabbitmq://localhost"), h => { h.Username("guest"); h.Password("guest"); }); x.ReceiveEndpoint(host, "request_service", e => { e.Consumer<RequestConsumer>(); }); }); _busControl.Start(); return true; } public bool Stop(HostControl hostControl) { _busControl.Stop(); return true; } } public class RequestConsumer : IConsumer<ISimpleRequest> { private readonly ILog _log = Logger.Get<RequestConsumer>(); public async Task Consume(ConsumeContext<ISimpleRequest> context) { _log.InfoFormat("I am consumer {0}", context.Message.CustomerId); Thread.Sleep(TimeSpan.FromSeconds(30)); context.Respond(new SimpleResponse { CusomerName = "Processing Finished " }); } private class SimpleResponse :ISimpleResponse { public string CusomerName { get; set; } } }

And these are the messages i send public interface ISimpleRequest { DateTime Timestamp { get; } string CustomerId { get; } }

public interface ISimpleResponse { string CusomerName { get; } } public class SimpleRequest : ISimpleRequest { private readonly string _customerId; private readonly DateTime _timestamp; public SimpleRequest(string customerId) { _customerId = customerId; _timestamp = DateTime.UtcNow; } public DateTime Timestamp { get { return _timestamp; } } public string CustomerId { get { return _customerId; } } }

Any tip would be really helpful.

I found a solution so if i use this

e.Consumer(() => { return reqConume; //this is a singleton });

and as a singleton instead of

e.Consumer();

in consumer then i have the same consumer instance and i can monitor the consumer directly. Send a cancel event to it as well. Sorry for the trouble guys

You should use the task cancellation to achieve this. As per MSDN

The System.Threading.Tasks.Task and System.Threading.Tasks.Task classes support cancellation through the use of cancellation tokens in the .NET Framework. For more information, see Cancellation in Managed Threads.

Please check the following link for more details https://msdn.microsoft.com/en-us/library/dd997396(v=vs.110).aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM