protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            this.TraceWriter.EnablePrefix = true;


#if _WAIT_FOR_DEBUGGER
            while (!Debugger.IsAttached)
                await Task.Delay(5000);
#endif

            // Create a work manager that is expected to receive a work item of type RouteToActor
            // The work manager will queue them (according to RouteToActor.Queue Name property). Then for each work 
            //item de-queued it will use RouteToActorWorkItemHandler type to process the work item
            this.WorkManager = new WorkManager<RoutetoActorWorkItemHandler, RouteToActorWorkItem>(this.StateManager, this.TraceWriter);


            // work manager will creates a new (RoutetoActorWorkItemHandler) 
            // per queue. our work item handling is basically forwarding event hub message to the Actor. 
            // since each Actor will have it is own queue (and a handler). each handler
            // can cache a reference to the actor proxy instead of caching them at a higher level
            this.WorkManager.WorkItemHandlerMode = WorkItemHandlerMode.PerQueue;

            // maximum # of worker loops (loops that de-queue from reliable queue)
            this.WorkManager.MaxNumOfWorkers = WorkManager<RoutetoActorWorkItemHandler, RouteToActorWorkItem>.s_Max_Num_OfWorker;

            this.WorkManager.YieldQueueAfter = 50; // worker will attempt to process
            // 50 work item per queue before dropping it 
            // and move to the next. 

            // if a queue stays empty more than .. it will be removed
            this.WorkManager.RemoveEmptyQueueAfter = TimeSpan.FromSeconds(10);

            // start it
            await this.WorkManager.StartAsync();

            // this wire up Event hub listeners that uses EventHubListenerDataHandler to 
            // post to WorkManager which then (create or get existing queue) then en-queue.
            this.eventHubListenerHandler = new EventHubListenerDataHandler(this.WorkManager);

            // this ensures that an event hub listener is created
            // per every assigned event hub
            await this.RefreshListenersAsync();

            while (!cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(2000);
            }


            this.TraceWriter.EnablePrefix = false;


            this.TraceWriter.TraceMessage("Replica is existing, stopping the work manager");

            try
            {
                await this.ClearEventHubListeners();
                await this.WorkManager.StopAsync();
            }
            catch (AggregateException aex)
            {
                AggregateException ae = aex.Flatten();
                this.TraceWriter.TraceMessage(
                    string.Format(
                        "as the replica unload (run async canceled) the followng errors occured E:{0} StackTrace:{1}",
                        aex.GetCombinedExceptionMessage(),
                        aex.GetCombinedExceptionStackTrace()));
            }
        }
Beispiel #2
0
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            this.TraceWriter.EnablePrefix = true;


#if _WAIT_FOR_DEBUGGER
            while (!Debugger.IsAttached)
            {
                await Task.Delay(5000);
            }
#endif

            // Create a work manager that is expected to receive a work item of type RouteToActor
            // The work manager will queue them (according to RouteToActor.Queue Name property). Then for each work
            //item de-queued it will use RouteToActorWorkItemHandler type to process the work item
            this.WorkManager = new WorkManager <RoutetoActorWorkItemHandler, RouteToActorWorkItem>(this.StateManager, this.TraceWriter);

            /*
             * Work Manager supports 2 modes
             * Buffered:
             *  - the original mode, items are buffered in reliable queues (one per device) then routed to actors.
             *  - the advantages of this mode, if you have smaller # of devices, the system will attempt to avoid the turn based concurrancy of the actor
             *    by fanning out execution, events are picked up from event hub faster than they are delivered to actors. this mode is good for large
             # of devices each is a high freq message sender.
             #
             # Buffered os faster on multi core CPUs , the max # of worker is 2 X CPU ore.
             #
             # None Buffered Mode:
             #  - newly introcuced mode, events are not buffered and routed directly to actors. this is a better mode if you expect large # of devices.
             #
             #
             # - You can extend the code to support switching at runtime (example: dealing with variable device #)
             #
             */
            this.WorkManager.BufferedMode = false;


            // work manager will creates a new (RoutetoActorWorkItemHandler)
            // per queue. our work item handling is basically forwarding event hub message to the Actor.
            // since each Actor will have it is own queue (and a handler). each handler
            // can cache a reference to the actor proxy instead of caching them at a higher level
            this.WorkManager.WorkItemHandlerMode = WorkItemHandlerMode.PerQueue;

            // maximum # of worker loops (loops that de-queue from reliable queue)
            this.WorkManager.MaxNumOfWorkers = WorkManager <RoutetoActorWorkItemHandler, RouteToActorWorkItem> .s_Max_Num_OfWorker;

            this.WorkManager.YieldQueueAfter = 50; // worker will attempt to process
            // 50 work item per queue before dropping it
            // and move to the next.

            // if a queue stays empty more than .. it will be removed
            this.WorkManager.RemoveEmptyQueueAfter = TimeSpan.FromSeconds(10);

            // start it
            await this.WorkManager.StartAsync();

            // this wire up Event hub listeners that uses EventHubListenerDataHandler to
            // post to WorkManager which then (create or get existing queue) then en-queue.
            this.eventHubListenerHandler = new EventHubListenerDataHandler(this.WorkManager);

            // this ensures that an event hub listener is created
            // per every assigned event hub
            await this.RefreshListenersAsync();

            while (!cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(2000);
            }


            this.TraceWriter.EnablePrefix = false;


            this.TraceWriter.TraceMessage("Replica is existing, stopping the work manager");

            try
            {
                await this.ClearEventHubListeners();

                await this.WorkManager.StopAsync();
            }
            catch (AggregateException aex)
            {
                AggregateException ae = aex.Flatten();
                this.TraceWriter.TraceMessage(
                    string.Format(
                        "as the replica unload (run async canceled) the followng errors occured E:{0} StackTrace:{1}",
                        aex.GetCombinedExceptionMessage(),
                        aex.GetCombinedExceptionStackTrace()));
            }
        }
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            this.TraceWriter.EnablePrefix = true;


#if _WAIT_FOR_DEBUGGER
            while (!Debugger.IsAttached)
                await Task.Delay(5000);
#endif

            // Create a work manager that is expected to receive a work item of type RouteToActor
            // The work manager will queue them (according to RouteToActor.Queue Name property). Then for each work 
            //item de-queued it will use RouteToActorWorkItemHandler type to process the work item
            this.WorkManager = new WorkManager<RoutetoActorWorkItemHandler, RouteToActorWorkItem>(this.StateManager, this.TraceWriter);

            /*
            Work Manager supports 2 modes
            Buffered: 
                - the original mode, items are buffered in reliable queues (one per device) then routed to actors.
                - the advantages of this mode, if you have smaller # of devices, the system will attempt to avoid the turn based concurrancy of the actor
                  by fanning out execution, events are picked up from event hub faster than they are delivered to actors. this mode is good for large
                  # of devices each is a high freq message sender. 
              
            Buffered os faster on multi core CPUs , the max # of worker is 2 X CPU ore.

            None Buffered Mode: 
                - newly introcuced mode, events are not buffered and routed directly to actors. this is a better mode if you expect large # of devices.
            
            
            - You can extend the code to support switching at runtime (example: dealing with variable device #)
            
            */
            this.WorkManager.BufferedMode = false; 


            // work manager will creates a new (RoutetoActorWorkItemHandler) 
            // per queue. our work item handling is basically forwarding event hub message to the Actor. 
            // since each Actor will have it is own queue (and a handler). each handler
            // can cache a reference to the actor proxy instead of caching them at a higher level
            this.WorkManager.WorkItemHandlerMode = WorkItemHandlerMode.PerQueue;

            // maximum # of worker loops (loops that de-queue from reliable queue)
            this.WorkManager.MaxNumOfWorkers =  WorkManager<RoutetoActorWorkItemHandler, RouteToActorWorkItem>.s_Max_Num_OfWorker;

            this.WorkManager.YieldQueueAfter = 50; // worker will attempt to process
            // 50 work item per queue before dropping it 
            // and move to the next. 

            // if a queue stays empty more than .. it will be removed
            this.WorkManager.RemoveEmptyQueueAfter = TimeSpan.FromSeconds(10);

            // start it
            await this.WorkManager.StartAsync();

            // this wire up Event hub listeners that uses EventHubListenerDataHandler to 
            // post to WorkManager which then (create or get existing queue) then en-queue.
            this.eventHubListenerHandler = new EventHubListenerDataHandler(this.WorkManager);

            // this ensures that an event hub listener is created
            // per every assigned event hub
            await this.RefreshListenersAsync();

            while (!cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(2000);
            }


            this.TraceWriter.EnablePrefix = false;


            this.TraceWriter.TraceMessage("Replica is existing, stopping the work manager");

            try
            {
                await this.ClearEventHubListeners();
                await this.WorkManager.StopAsync();
            }
            catch (AggregateException aex)
            {
                AggregateException ae = aex.Flatten();
                this.TraceWriter.TraceMessage(
                    string.Format(
                        "as the replica unload (run async canceled) the followng errors occured E:{0} StackTrace:{1}",
                        aex.GetCombinedExceptionMessage(),
                        aex.GetCombinedExceptionStackTrace()));
            }
        }
        protected override async Task RunAsync(CancellationToken cancellationToken)
        {
            this.TraceWriter.EnablePrefix = true;


#if _WAIT_FOR_DEBUGGER
            while (!Debugger.IsAttached)
            {
                await Task.Delay(5000);
            }
#endif

            // Create a work manager that is expected to receive a work item of type RouteToActor
            // The work manager will queue them (according to RouteToActor.Queue Name property). Then for each work
            //item de-queued it will use RouteToActorWorkItemHandler type to process the work item
            this.WorkManager = new WorkManager <RoutetoActorWorkItemHandler, RouteToActorWorkItem>(this.StateManager, this.TraceWriter);


            // work manager will creates a new (RoutetoActorWorkItemHandler)
            // per queue. our work item handling is basically forwarding event hub message to the Actor.
            // since each Actor will have it is own queue (and a handler). each handler
            // can cache a reference to the actor proxy instead of caching them at a higher level
            this.WorkManager.WorkItemHandlerMode = WorkItemHandlerMode.PerQueue;

            // maximum # of worker loops (loops that de-queue from reliable queue)
            this.WorkManager.MaxNumOfWorkers = WorkManager <RoutetoActorWorkItemHandler, RouteToActorWorkItem> .s_Max_Num_OfWorker;

            this.WorkManager.YieldQueueAfter = 50; // worker will attempt to process
            // 50 work item per queue before dropping it
            // and move to the next.

            // if a queue stays empty more than .. it will be removed
            this.WorkManager.RemoveEmptyQueueAfter = TimeSpan.FromSeconds(10);

            // start it
            await this.WorkManager.StartAsync();

            // this wire up Event hub listeners that uses EventHubListenerDataHandler to
            // post to WorkManager which then (create or get existing queue) then en-queue.
            this.eventHubListenerHandler = new EventHubListenerDataHandler(this.WorkManager);

            // this ensures that an event hub listener is created
            // per every assigned event hub
            await this.RefreshListenersAsync();

            while (!cancellationToken.IsCancellationRequested)
            {
                await Task.Delay(2000);
            }


            this.TraceWriter.EnablePrefix = false;


            this.TraceWriter.TraceMessage("Replica is existing, stopping the work manager");

            try
            {
                await this.ClearEventHubListeners();

                await this.WorkManager.StopAsync();
            }
            catch (AggregateException aex)
            {
                AggregateException ae = aex.Flatten();
                this.TraceWriter.TraceMessage(
                    string.Format(
                        "as the replica unload (run async canceled) the followng errors occured E:{0} StackTrace:{1}",
                        aex.GetCombinedExceptionMessage(),
                        aex.GetCombinedExceptionStackTrace()));
            }
        }