예제 #1
0
        /// <summary>
        /// It's a delicate difference between <see cref="CoordinatedShutdown.PhaseClusterExiting"/> and <see cref="ClusterEvent.MemberExited"/>.
        ///
        /// MemberExited event is published immediately (leader may have performed that transition on other node),
        /// and that will trigger run of <see cref="CoordinatedShutdown"/>, while PhaseClusterExiting will happen later.
        /// Using PhaseClusterExiting in the singleton because the graceful shutdown of sharding region
        /// should preferably complete before stopping the singleton sharding coordinator on same node.
        /// </summary>
        private void SetupCoordinatedShutdown()
        {
            var self = Self;

            _coordShutdown.AddTask(CoordinatedShutdown.PhaseClusterExiting, "singleton-exiting-1", () =>
            {
                var timeout = _coordShutdown.Timeout(CoordinatedShutdown.PhaseClusterExiting);
                return(self.Ask(SelfExiting.Instance, timeout).ContinueWith(tr => Done.Instance));
            });
        }
예제 #2
0
        private void SetupCoordinatedShutdown()
        {
            var self = Self;

            _coordShutdown.AddTask(CoordinatedShutdown.PhaseClusterShardingShutdownRegion, "region-shutdown", () =>
            {
                self.Tell(GracefulShutdown.Instance);
                return(_gracefulShutdownProgress.Task);
            });
        }
예제 #3
0
        public void CoordinatedShutdown_must_continue_after_timeout_or_failure()
        {
            var phases = new Dictionary <string, Phase>()
            {
                { "a", EmptyPhase },
                { "b", new Phase(ImmutableHashSet <string> .Empty.Add("a"), TimeSpan.FromMilliseconds(100), true) },
                { "c", Phase("b", "a") }
            };

            var co = new CoordinatedShutdown(ExtSys, phases);

            co.AddTask("a", "a1", () =>
            {
                TestActor.Tell("A");
                return(TaskEx.FromException <Done>(new Exception("boom")));
            });

            co.AddTask("a", "a2", () =>
            {
                Task.Delay(TimeSpan.FromMilliseconds(100)).Wait();
                TestActor.Tell("A");
                return(TaskEx.Completed);
            });

            co.AddTask("b", "b1", () =>
            {
                TestActor.Tell("B");
                return(new TaskCompletionSource <Done>().Task); // never completed
            });

            co.AddTask("c", "c1", () =>
            {
                TestActor.Tell("C");
                return(TaskEx.Completed);
            });

            co.Run(CoordinatedShutdown.UnknownReason.Instance).Wait(RemainingOrDefault);
            ExpectMsg("A");
            ExpectMsg("A");
            ExpectMsg("B");
            ExpectMsg("C");
        }
예제 #4
0
        public void CoordinatedShutdown_must_run_ordered_phases()
        {
            var phases = new Dictionary <string, Phase>()
            {
                { "a", EmptyPhase },
                { "b", Phase("a") },
                { "c", Phase("b", "a") }
            };

            var co = new CoordinatedShutdown(ExtSys, phases);

            co.AddTask("a", "a1", () =>
            {
                TestActor.Tell("A");
                return(TaskEx.Completed);
            });

            co.AddTask("b", "b1", () =>
            {
                TestActor.Tell("B");
                return(TaskEx.Completed);
            });

            co.AddTask("b", "b2", () =>
            {
                // to verify that c is not performed before b
                Task.Delay(TimeSpan.FromMilliseconds(100)).Wait();
                TestActor.Tell("B");
                return(TaskEx.Completed);
            });

            co.AddTask("c", "c1", () =>
            {
                TestActor.Tell("C");
                return(TaskEx.Completed);
            });

            co.Run(CoordinatedShutdown.UnknownReason.Instance).Wait(RemainingOrDefault);
            ReceiveN(4).Should().Equal(new object[] { "A", "B", "B", "C" });
        }
예제 #5
0
        public void CoordinatedShutdown_must_abort_if_recover_is_off()
        {
            var phases = new Dictionary <string, Phase>()
            {
                { "b", new Phase(ImmutableHashSet <string> .Empty.Add("a"), TimeSpan.FromMilliseconds(100), false) },
                { "c", Phase("b", "a") }
            };

            var co = new CoordinatedShutdown(ExtSys, phases);

            co.AddTask("b", "b1", () =>
            {
                TestActor.Tell("B");
                return(new TaskCompletionSource <Done>().Task); // never completed
            });

            co.AddTask("c", "c1", () =>
            {
                TestActor.Tell("C");
                return(TaskEx.Completed);
            });

            var result = co.Run(CoordinatedShutdown.UnknownReason.Instance);

            ExpectMsg("B");
            Intercept <AggregateException>(() =>
            {
                if (result.Wait(RemainingOrDefault))
                {
                    result.Exception?.Flatten().InnerException.Should().BeOfType <TimeoutException>();
                }
                else
                {
                    throw new Exception("CoordinatedShutdown task did not complete");
                }
            });

            ExpectNoMsg(TimeSpan.FromMilliseconds(200)); // C not run
        }
예제 #6
0
        /// <summary>
        /// It's a delicate difference between <see cref="CoordinatedShutdown.PhaseClusterExiting"/> and <see cref="ClusterEvent.MemberExited"/>.
        ///
        /// MemberExited event is published immediately (leader may have performed that transition on other node),
        /// and that will trigger run of <see cref="CoordinatedShutdown"/>, while PhaseClusterExiting will happen later.
        /// Using PhaseClusterExiting in the singleton because the graceful shutdown of sharding region
        /// should preferably complete before stopping the singleton sharding coordinator on same node.
        /// </summary>
        private void SetupCoordinatedShutdown()
        {
            var self = Self;

            _coordShutdown.AddTask(CoordinatedShutdown.PhaseClusterExiting, "singleton-exiting-1", () =>
            {
                if (_cluster.IsTerminated || _cluster.SelfMember.Status == MemberStatus.Down)
                {
                    return(Task.FromResult(Done.Instance));
                }
                else
                {
                    var timeout = _coordShutdown.Timeout(CoordinatedShutdown.PhaseClusterExiting);
                    return(self.Ask(SelfExiting.Instance, timeout).ContinueWith(tr => Done.Instance));
                }
            });
        }
예제 #7
0
        private void SetupCoordinatedShutdown()
        {
            var self = Self;

            _coordShutdown.AddTask(CoordinatedShutdown.PhaseClusterShardingShutdownRegion, "region-shutdown", () =>
            {
                if (Cluster.IsTerminated || Cluster.SelfMember.Status == MemberStatus.Down)
                {
                    return(Task.FromResult(Done.Instance));
                }
                else
                {
                    self.Tell(GracefulShutdown.Instance);
                    return(_gracefulShutdownProgress.Task);
                }
            });
        }
        public void CoordinatedShutdown_must_only_run_once()
        {
            var phases = new Dictionary <string, Phase>()
            {
                { "a", EmptyPhase }
            };

            var co = new CoordinatedShutdown(ExtSys, phases);

            co.AddTask("a", "a1", () =>
            {
                TestActor.Tell("A");
                return(TaskEx.Completed);
            });

            co.Run().Wait(RemainingOrDefault);
            ExpectMsg("A");
            co.Run().Wait(RemainingOrDefault);
            TestActor.Tell("done");
            ExpectMsg("done"); // no additional A
        }
예제 #9
0
        public void CoordinatedShutdown_must_only_run_once()
        {
            var phases = new Dictionary <string, Phase>()
            {
                { "a", EmptyPhase }
            };

            var co = new CoordinatedShutdown(ExtSys, phases);

            co.AddTask("a", "a1", () =>
            {
                TestActor.Tell("A");
                return(TaskEx.Completed);
            });

            co.ShutdownReason.Should().BeNull();
            co.Run(customReason).Wait(RemainingOrDefault);
            co.ShutdownReason.ShouldBeEquivalentTo(customReason);
            ExpectMsg("A");
            co.Run(CoordinatedShutdown.UnknownReason.Instance).Wait(RemainingOrDefault);
            TestActor.Tell("done");
            ExpectMsg("done"); // no additional A
            co.ShutdownReason.ShouldBeEquivalentTo(customReason);
        }