Beispiel #1
0
        public MultiClusterOracle(
            ILocalSiloDetails siloDetails,
            MultiClusterGossipChannelFactory channelFactory,
            ISiloStatusOracle siloStatusOracle,
            MembershipTableManager tableManager,
            IInternalGrainFactory grainFactory,
            ILoggerFactory loggerFactory,
            IOptions <MultiClusterOptions> multiClusterOptions)
            : base(Constants.MultiClusterOracleId, siloDetails.SiloAddress, loggerFactory)
        {
            this.loggerFactory    = loggerFactory;
            this.channelFactory   = channelFactory;
            this.siloStatusOracle = siloStatusOracle;
            this.tableManager     = tableManager;
            this.grainFactory     = grainFactory;

            logger    = loggerFactory.CreateLogger <MultiClusterOracle>();
            localData = new MultiClusterOracleData(logger, grainFactory);
            clusterId = siloDetails.ClusterId;
            var multiClusterOptionsSnapshot = multiClusterOptions.Value;

            defaultMultiCluster          = multiClusterOptionsSnapshot.DefaultMultiCluster?.ToList();
            this.multiClusterActive      = multiClusterOptionsSnapshot.HasMultiClusterNetwork;
            this.maxMultiClusterGateways = multiClusterOptionsSnapshot.MaxMultiClusterGateways;
            random = new SafeRandom();

            // to avoid convoying, each silo varies these period intervals a little
            backgroundGossipInterval = RandomizeTimespanSlightly(multiClusterOptionsSnapshot.BackgroundGossipInterval);
            resendActiveStatusAfter  = RandomizeTimespanSlightly(ResendActiveStatusAfter);
        }
Beispiel #2
0
 public ManagementGrain(
     IInternalGrainFactory internalGrainFactory,
     ISiloStatusOracle siloStatusOracle,
     GrainTypeManager grainTypeManager,
     IVersionStore versionStore,
     ILogger <ManagementGrain> logger,
     MembershipTableManager membershipTableManager)
 {
     this.membershipTableManager = membershipTableManager;
     this.internalGrainFactory   = internalGrainFactory;
     this.siloStatusOracle       = siloStatusOracle;
     this.grainTypeManager       = grainTypeManager;
     this.versionStore           = versionStore;
     this.logger = logger;
 }
 public ManagementGrain(
     IInternalGrainFactory internalGrainFactory,
     ISiloStatusOracle siloStatusOracle,
     IVersionStore versionStore,
     ILogger <ManagementGrain> logger,
     MembershipTableManager membershipTableManager,
     IClusterManifestProvider clusterManifestProvider)
 {
     this.membershipTableManager = membershipTableManager;
     this.siloManifest           = clusterManifestProvider.LocalGrainManifest;
     this.internalGrainFactory   = internalGrainFactory;
     this.siloStatusOracle       = siloStatusOracle;
     this.versionStore           = versionStore;
     this.logger = logger;
 }
Beispiel #4
0
 public ClusterMembershipService(
     MembershipTableManager membershipTableManager,
     ILogger <ClusterMembershipService> log,
     IFatalErrorHandler fatalErrorHandler)
 {
     this.snapshot = membershipTableManager.MembershipTableSnapshot.CreateClusterMembershipSnapshot();
     this.updates  = new AsyncEnumerable <ClusterMembershipSnapshot>(
         (previous, proposed) => proposed.Version == MembershipVersion.MinValue || proposed.Version > previous.Version,
         this.snapshot)
     {
         OnPublished = update => Interlocked.Exchange(ref this.snapshot, update)
     };
     this.membershipTableManager = membershipTableManager;
     this.log = log;
     this.fatalErrorHandler = fatalErrorHandler;
 }
 public ManagementGrain(
     IOptions <MultiClusterOptions> multiClusterOptions,
     IMultiClusterOracle multiClusterOracle,
     IInternalGrainFactory internalGrainFactory,
     ISiloStatusOracle siloStatusOracle,
     GrainTypeManager grainTypeManager,
     IVersionStore versionStore,
     ILogger <ManagementGrain> logger,
     MembershipTableManager membershipTableManager)
 {
     this.membershipTableManager = membershipTableManager;
     this.multiClusterOptions    = multiClusterOptions.Value;
     this.multiClusterOracle     = multiClusterOracle;
     this.internalGrainFactory   = internalGrainFactory;
     this.siloStatusOracle       = siloStatusOracle;
     this.grainTypeManager       = grainTypeManager;
     this.versionStore           = versionStore;
     this.logger = logger;
 }
Beispiel #6
0
        private async Task BasicScenarioTest(InMemoryMembershipTable membershipTable, bool gracefulShutdown = true)
        {
            var timers       = new List <DelegateAsyncTimer>();
            var timerCalls   = new ConcurrentQueue <(TimeSpan?DelayOverride, TaskCompletionSource <bool> Completion)>();
            var timerFactory = new DelegateAsyncTimerFactory(
                (period, name) =>
            {
                var timer = new DelegateAsyncTimer(
                    overridePeriod =>
                {
                    var task = new TaskCompletionSource <bool>();
                    timerCalls.Enqueue((overridePeriod, task));
                    return(task.Task);
                });
                timers.Add(timer);
                return(timer);
            });

            var manager = new MembershipTableManager(
                localSiloDetails: this.localSiloDetails,
                clusterMembershipOptions: Options.Create(new ClusterMembershipOptions()),
                membershipTable: membershipTable,
                fatalErrorHandler: this.fatalErrorHandler,
                gossiper: this.membershipGossiper,
                log: this.loggerFactory.CreateLogger <MembershipTableManager>(),
                timerFactory: timerFactory,
                this.lifecycle);

            // Validate that the initial snapshot is valid and contains the local silo.
            var initialSnapshot = manager.MembershipTableSnapshot;

            Assert.NotNull(initialSnapshot);
            Assert.NotNull(initialSnapshot.Entries);
            Assert.NotNull(initialSnapshot.LocalSilo);
            Assert.Equal(SiloStatus.Created, initialSnapshot.LocalSilo.Status);
            Assert.Equal(this.localSiloDetails.Name, initialSnapshot.LocalSilo.SiloName);
            Assert.Equal(this.localSiloDetails.DnsHostName, initialSnapshot.LocalSilo.HostName);
            Assert.Equal(SiloStatus.Created, manager.CurrentStatus);

            Assert.NotNull(manager.MembershipTableUpdates);
            var changes           = manager.MembershipTableUpdates;
            var currentEnumerator = changes.GetAsyncEnumerator();

            Assert.True(currentEnumerator.MoveNextAsync().Result);
            Assert.Equal(currentEnumerator.Current.Version, manager.MembershipTableSnapshot.Version);
            Assert.Empty(membershipTable.Calls);

            // All of these checks were performed before any lifecycle methods have a chance to run.
            // This is in order to verify that a service accessing membership in its constructor will
            // see the correct results regardless of initialization order.
            ((ILifecycleParticipant <ISiloLifecycle>)manager).Participate(this.lifecycle);

            await this.lifecycle.OnStart();

            var calls = membershipTable.Calls;

            Assert.NotEmpty(calls);
            Assert.True(calls.Count >= 2);
            Assert.Equal(nameof(IMembershipTable.InitializeMembershipTable), calls[0].Method);
            Assert.Equal(nameof(IMembershipTable.ReadAll), calls[1].Method);

            // During initialization, a first read from the table will be performed, transitioning
            // membership to a valid version.currentEnumerator = changes.GetAsyncEnumerator();
            currentEnumerator = changes.GetAsyncEnumerator();
            Assert.True(currentEnumerator.MoveNextAsync().Result);
            var update1 = currentEnumerator.Current;

            // Transition to joining.
            this.membershipGossiper.ClearReceivedCalls();
            await manager.UpdateStatus(SiloStatus.Joining);

            await this.membershipGossiper.ReceivedWithAnyArgs().GossipToRemoteSilos(default, default, default);
Beispiel #7
0
 public SiloRoleBasedPlacementDirector(MembershipTableManager membershipTableManager)
 {
     this.membershipTableManager = membershipTableManager;
 }