/// <summary> /// Creates a Cluster instance from a single TouchInput /// </summary> /// <param name="point"></param> public Cluster(TouchInput point) { this.AddPoint(point.Id); this._hashId = "#" + point.Id; this._centroid = point.Position; _state = ClusterState.Invalid; }
public Task TestUpdateRingAndGetLocations() { return(RunTestAsync(async(context, store, directory) => { ClusterState clusterState = ClusterState.CreateForTest(); for (int i = 0; i <= 10; i++) { var machineId = new MachineId(i); var machineLocation = new MachineLocation(i.ToString()); clusterState.AddMachine(machineId, machineLocation); } var contentHashes = new List <ContentHashWithPath>(); var contentHash1 = new ContentHashWithPath(new ContentHash("MD5:72F6F256239CC69B6FE9AF1C7489CFD1"), directory.Path / "hash1"); var contentHash2 = new ContentHashWithPath(new ContentHash("MD5:61C4F184221AD54A2FA4A92A6137AA42"), directory.Path / "hash2"); contentHashes.Add(contentHash1); contentHashes.Add(contentHash2); var result = await store.UpdateRingAsync(context, clusterState).ShouldBeSuccess(); var locations = store.GetBulkLocations(context, contentHashes).ShouldBeSuccess(); locations.Count.Should().Be(2); locations.ContentHashesInfo[0].ContentHash.Serialize().Should().Be("MD5:72F6F256239CC69B6FE9AF1C7489CFD1"); locations.ContentHashesInfo[0].Locations[0].ToString().Should().Be("6"); locations.ContentHashesInfo[0].Locations[1].ToString().Should().Be("4"); locations.ContentHashesInfo[0].Locations[2].ToString().Should().Be("5"); locations.ContentHashesInfo[1].ContentHash.Serialize().Should().Be("MD5:61C4F184221AD54A2FA4A92A6137AA42"); locations.ContentHashesInfo[1].Locations[0].ToString().Should().Be("10"); locations.ContentHashesInfo[1].Locations[1].ToString().Should().Be("1"); locations.ContentHashesInfo[1].Locations[2].ToString().Should().Be("3"); })); }
public void SetUp() { settings = new RelativeWeightSettings() { WeightUpdatePeriod = 200.Milliseconds(), PenaltyMultiplier = 100, InitialWeight = 1, StatisticSmoothingConstant = 100.Milliseconds(), WeightsDownSmoothingConstant = 100.Milliseconds(), WeightsRaiseSmoothingConstant = 100.Milliseconds(), WeightsTTL = 5.Minutes(), MinWeight = 0.005, Sensitivity = 3 }; clusterState = new ClusterState( timeProvider: Substitute.For <ITimeProvider>(), rawClusterStatistic: Substitute.For <IRawClusterStatistic>(), statisticHistory: Substitute.For <IStatisticHistory>(), relativeWeightCalculator: Substitute.For <IRelativeWeightCalculator>(), weightsNormalizer: Substitute.For <IWeightsNormalizer>(), weights: Substitute.For <IWeights>()); replicaStorageProvider = Substitute.For <IReplicaStorageProvider>(); storageProvider = Substitute.For <IGlobalStorageProvider>(); storageProvider.ObtainGlobalValue(Arg.Any <string>(), Arg.Any <Func <ClusterState> >()) .Returns(info => clusterState); relativeWeightModifier = new RelativeWeightModifier(settings, "srv", "env", 0, 1, storageProvider); }
private ClusterState GetClusterInfo(string id, string policy, bool enabled = true) { var clusterModel = new ClusterModel( new ClusterConfig { ClusterId = id, HealthCheck = new HealthCheckConfig { Passive = new PassiveHealthCheckConfig { Enabled = enabled, Policy = policy, } } }, new HttpMessageInvoker(new HttpClientHandler())); var clusterState = new ClusterState(id); clusterState.Model = clusterModel; clusterState.Destinations.GetOrAdd("destination0", id => new DestinationState(id)); clusterState.Destinations.GetOrAdd("destination1", id => new DestinationState(id)); clusterState.DestinationsState = new ClusterDestinationsState(clusterState.Destinations.Values.ToList(), clusterState.Destinations.Values.ToList()); return(clusterState); }
public void PickDestination_RoundRobin_Works() { var destinations = new[] { new DestinationState("d1"), new DestinationState("d2"), new DestinationState("d3") }; destinations[0].ConcurrentRequestCount++; var context = new DefaultHttpContext(); var cluster = new ClusterState("cluster1"); var routeConfig = new RouteModel(new RouteConfig(), cluster, HttpTransformer.Default); var feature = new ReverseProxyFeature() { Route = routeConfig, }; context.Features.Set <IReverseProxyFeature>(feature); var loadBalancer = Create <RoundRobinLoadBalancingPolicy>(); for (var i = 0; i < 10; i++) { var result = loadBalancer.PickDestination(context, cluster, availableDestinations: destinations); Assert.Same(destinations[i % destinations.Length], result); result.ConcurrentRequestCount++; } }
public void AddEndpoint_JustHost_Works() { var services = CreateServices(); var factory = services.GetRequiredService <ProxyEndpointFactory>(); factory.SetProxyPipeline(context => Task.CompletedTask); var route = new RouteConfig { RouteId = "route1", Match = new RouteMatch { Hosts = new[] { "example.com" }, }, Order = 12, }; var cluster = new ClusterState("cluster1"); var routeState = new RouteState("route1"); var(routeEndpoint, routeConfig) = CreateEndpoint(factory, routeState, route, cluster); Assert.Same(cluster, routeConfig.Cluster); Assert.Equal("route1", routeEndpoint.DisplayName); Assert.Same(routeConfig, routeEndpoint.Metadata.GetMetadata <RouteModel>()); Assert.Equal("/{**catchall}", routeEndpoint.RoutePattern.RawText); Assert.Equal(12, routeEndpoint.Order); Assert.False(routeConfig.HasConfigChanged(route, cluster, routeState.ClusterRevision)); var hostMetadata = routeEndpoint.Metadata.GetMetadata <HostAttribute>(); Assert.NotNull(hostMetadata); Assert.Single(hostMetadata.Hosts); Assert.Equal("example.com", hostMetadata.Hosts[0]); }
public Cluster RemovePoint(int touchId) { _pointsIds.Remove(touchId); _points.Remove(touchId); UpdateCentroid(); if (State == ClusterState.Identidied || State == ClusterState.Updated) { _state = ClusterState.Cancelled; _cancelledHash = this._hashId; _cancelledPointsIds.Add(touchId); } else if (State == ClusterState.Cancelled) { _cancelledPointsIds.Add(touchId); } else if (_pointsIds.Count == 4) { _state = ClusterState.Unidentified; } else { _state = ClusterState.Invalid; } this._hashId = GetPointsHash(_pointsIds.ToArray <int>()); return(this); }
private static ClusterState CreateCluster(bool passive, bool active, params DestinationState[] destinations) { var cluster = new ClusterState("cluster0"); cluster.Model = new ClusterModel( new ClusterConfig { ClusterId = cluster.ClusterId, HealthCheck = new HealthCheckConfig() { Passive = new PassiveHealthCheckConfig() { Policy = "policy0", Enabled = passive, }, Active = new ActiveHealthCheckConfig() { Enabled = active, Policy = "policy1", }, }, }, new HttpMessageInvoker(new HttpClientHandler())); foreach (var destination in destinations) { cluster.Destinations.TryAdd(destination.DestinationId, destination); } cluster.DestinationsState = new ClusterDestinationsState(destinations, destinations); return(cluster); }
private RingNode[] CreateNewRing(ClusterState clusterState) { MachineId currentMachineId = clusterState.PrimaryMachineId; SortedList <long, RingNode> sortedMachines = new SortedList <long, RingNode>(); IReadOnlyList <MachineLocation> machineLocations = clusterState.Locations; MachineId machineId; foreach (var machine in machineLocations) { // We use the machineId to place it in the virtual ring bool success = clusterState.TryResolveMachineId(machine, out machineId); // Create the consistent-hashing virtual ring with the active servers if (success && !clusterState.IsMachineMarkedInactive(machineId) && currentMachineId != machineId) { long id = _contentHasher.GetContentHash( BitConverter.GetBytes(machineId.Index) ).LeastSignificantLong(); sortedMachines.Add(id, new RingNode(id, machine)); } } return(sortedMachines.Values.ToArray()); }
/// <summary> /// Close all resources related to the cluster. Attempts to do so in a graceful manner, flushing /// </summary> /// <param name="timeout"></param> /// <returns></returns> public async Task CloseAsync(TimeSpan timeout) { if (_state == ClusterState.Disconnected || _state == ClusterState.Closed) { return; } _log.Info("#{0} Closing...", _id); EtwTrace.Log.ClusterStopping(_id); // wait on the partition recovery monitor and all of the correlation loops to shut down. var success = await await Scheduler.Ask(async() => await CloseAsyncImpl().TimeoutAfter(timeout) ).ConfigureAwait(false); if (!success) { _log.Error("Timed out"); EtwTrace.Log.ClusterError(_id, "Timeout on close"); if (!_partitionRecoveryMonitor.Completion.IsCompleted) { _log.Error("_partitionRecoveryMonitor timed out"); } } else { _log.Info("#{0} Closed", _id); EtwTrace.Log.ClusterStopped(_id); } Scheduler.Dispose(); _state = ClusterState.Disconnected; }
public void BuildEndpoints_Headers_Works() { var services = CreateServices(); var factory = services.GetRequiredService <ProxyEndpointFactory>(); factory.SetProxyPipeline(context => Task.CompletedTask); var route = new RouteConfig { RouteId = "route1", Match = new RouteMatch { Path = "/", Headers = new[] { new RouteHeader() { Name = "header1", Values = new[] { "value1" }, Mode = HeaderMatchMode.HeaderPrefix, IsCaseSensitive = true, }, new RouteHeader() { Name = "header2", Mode = HeaderMatchMode.Exists, } } }, }; var cluster = new ClusterState("cluster1"); var routeState = new RouteState("route1"); var(routeEndpoint, routeConfig) = CreateEndpoint(factory, routeState, route, cluster); Assert.Same(cluster, routeConfig.Cluster); Assert.Equal("route1", routeEndpoint.DisplayName); var metadata = routeEndpoint.Metadata.GetMetadata <IHeaderMetadata>(); Assert.Equal(2, metadata.Matchers.Length); var firstMetadata = metadata.Matchers.First(); Assert.NotNull(firstMetadata); Assert.Equal("header1", firstMetadata.Name); Assert.Equal(new[] { "value1" }, firstMetadata.Values); Assert.Equal(HeaderMatchMode.HeaderPrefix, firstMetadata.Mode); Assert.Equal(StringComparison.Ordinal, firstMetadata.Comparison); var secondMetadata = metadata.Matchers.Skip(1).Single(); Assert.NotNull(secondMetadata); Assert.Equal("header2", secondMetadata.Name); Assert.Same(Array.Empty <string>(), secondMetadata.Values); Assert.Equal(HeaderMatchMode.Exists, secondMetadata.Mode); Assert.Equal(StringComparison.OrdinalIgnoreCase, secondMetadata.Comparison); Assert.False(routeConfig.HasConfigChanged(route, cluster, routeState.ClusterRevision)); }
private HttpContext GetContext(ClusterState cluster, int selectedDestination, IForwarderErrorFeature error) { var context = new DefaultHttpContext(); context.Features.Set(GetProxyFeature(cluster, cluster.DestinationsState.AllDestinations[selectedDestination])); context.Features.Set(error); return(context); }
public void UpdateAllDestinations(ClusterState cluster) { // Values already makes a copy of the collection, downcast to avoid making a second copy. // https://github.com/dotnet/runtime/blob/e164551f1c96138521b4e58f14f8ac1e4369005d/src/libraries/System.Collections.Concurrent/src/System/Collections/Concurrent/ConcurrentDictionary.cs#L2145-L2168 var allDestinations = (IReadOnlyList <DestinationState>)cluster.Destinations.Values; UpdateInternal(cluster, allDestinations, force: true); }
public void RequestProxied(ClusterState cluster, DestinationState destination, HttpContext context) { var error = context.Features.Get <IProxyErrorFeature>(); var newHealth = EvaluateProxiedRequest(cluster, destination, error != null); var reactivationPeriod = cluster.Model.Config.HealthCheck?.Passive?.ReactivationPeriod ?? _defaultReactivationPeriod; _healthUpdater.SetPassive(cluster, destination, newHealth, reactivationPeriod); }
public void OnClusterChanged(ClusterState cluster) { var config = cluster.Model.Config.HealthCheck?.Active; if (config is not null && config.Enabled.GetValueOrDefault()) { Scheduler.ChangePeriod(cluster, config.Interval ?? _monitorOptions.DefaultInterval); }
public override ClusterState Advance(ClusterState previous) { ClusterState newClusterState = new ClusterState(previous); LinkedList <Org.Neo4j.causalclustering.core.consensus.RaftMessages_RaftMessage> newQueue = new LinkedList <Org.Neo4j.causalclustering.core.consensus.RaftMessages_RaftMessage>(previous.Queues[_member]); newQueue.AddLast(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_Timeout_Heartbeat(_member)); newClusterState.Queues[_member] = newQueue; return(newClusterState); }
public override ClusterState Advance(ClusterState previous) { ClusterState newClusterState = new ClusterState(previous); LinkedList <Org.Neo4j.causalclustering.core.consensus.RaftMessages_RaftMessage> newQueue = new LinkedList <Org.Neo4j.causalclustering.core.consensus.RaftMessages_RaftMessage>(previous.Queues[_member]); newQueue.AddLast(new Org.Neo4j.causalclustering.core.consensus.RaftMessages_NewEntry_Request(_member, new ReplicatedString("content"))); newClusterState.Queues[_member] = newQueue; return(newClusterState); }
public void RequestProxied(HttpContext context, ClusterState cluster, DestinationState destination) { var newHealth = EvaluateProxiedRequest(cluster, destination, DetermineIfDestinationFailed(context)); var clusterReactivationPeriod = cluster.Model.Config.HealthCheck?.Passive?.ReactivationPeriod ?? _defaultReactivationPeriod; // Avoid reactivating until the history has expired so that it does not affect future health assessments. var reactivationPeriod = clusterReactivationPeriod >= _policyOptions.DetectionWindowSize ? clusterReactivationPeriod : _policyOptions.DetectionWindowSize; _healthUpdater.SetPassive(cluster, destination, newHealth, reactivationPeriod); }
public void OnClusterAdded(ClusterState cluster) { var config = cluster.Model.Config.HealthCheck?.Active; if (config != null && config.Enabled.GetValueOrDefault()) { Scheduler.ScheduleEntity(cluster, config.Interval ?? _monitorOptions.DefaultInterval); } }
private IReverseProxyFeature GetProxyFeature(ClusterState clusterState, DestinationState destination) { return(new ReverseProxyFeature() { ProxiedDestination = destination, Cluster = clusterState.Model, Route = new RouteModel(new RouteConfig(), clusterState, HttpTransformer.Default), }); }
public void SetClusterState(int absoluteClusterNumber, ClusterState value) { if (_readOnly) { throw new NotSupportedException(); } lock (_lock) _clusterStateTable[absoluteClusterNumber] = value; }
public async Task Invoke_NoHealthyEndpoints_CallsNext() { var httpClient = new HttpMessageInvoker(new Mock <HttpMessageHandler>().Object); var cluster1 = new ClusterState(clusterId: "cluster1"); cluster1.Model = new ClusterModel( new ClusterConfig() { HealthCheck = new HealthCheckConfig { Active = new ActiveHealthCheckConfig { Enabled = true, Timeout = Timeout.InfiniteTimeSpan, Interval = Timeout.InfiniteTimeSpan, Policy = "Any5xxResponse", } } }, httpClient); var destination1 = cluster1.Destinations.GetOrAdd( "destination1", id => new DestinationState(id) { Model = new DestinationModel(new DestinationConfig { Address = "https://localhost:123/a/b/" }), Health = { Active = DestinationHealth.Unhealthy }, }); cluster1.DestinationsState = new ClusterDestinationsState(new[] { destination1 }, Array.Empty <DestinationState>()); var aspNetCoreEndpoints = new List <Endpoint>(); var routeConfig = new RouteModel( config: new RouteConfig(), cluster: cluster1, transformer: HttpTransformer.Default); var aspNetCoreEndpoint = CreateAspNetCoreEndpoint(routeConfig); aspNetCoreEndpoints.Add(aspNetCoreEndpoint); var httpContext = new DefaultHttpContext(); httpContext.SetEndpoint(aspNetCoreEndpoint); var sut = Create <ProxyPipelineInitializerMiddleware>(); await sut.Invoke(httpContext); var feature = httpContext.Features.Get <IReverseProxyFeature>(); Assert.NotNull(feature); Assert.Single(feature.AllDestinations, destination1); Assert.Empty(feature.AvailableDestinations); Assert.Equal(StatusCodes.Status418ImATeapot, httpContext.Response.StatusCode); }
private void UpdateInternal(ClusterState cluster, IReadOnlyList <DestinationState> allDestinations, bool force) { // Prevent overlapping updates and debounce extra concurrent calls. // If there are multiple concurrent calls to rebuild the dynamic state, we want to ensure that // updates don't conflict with each other. Additionally, we debounce extra concurrent calls if // they arrive in a quick succession to avoid spending too much CPU on frequent state rebuilds. // Specifically, only up to two threads are allowed to wait here and actually execute a rebuild, // all others will be debounced and the call will return without updating the ClusterState.DestinationsState. // However, changes made by those debounced threads (e.g. destination health updates) will be // taken into account by one of blocked threads after they get unblocked to run a rebuild. var updateLock = _clusterLocks.GetValue(cluster, _ => new SemaphoreSlim(2)); var lockTaken = false; if (force) { lockTaken = true; updateLock.Wait(); } else { lockTaken = updateLock.Wait(0); } if (!lockTaken) { return; } lock (updateLock) { try { var config = cluster.Model.Config; var destinationPolicy = _destinationPolicies.GetRequiredServiceById( config.HealthCheck?.AvailableDestinationsPolicy, HealthCheckConstants.AvailableDestinations.HealthyAndUnknown); var availableDestinations = destinationPolicy.GetAvailalableDestinations(config, allDestinations); cluster.DestinationsState = new ClusterDestinationsState(allDestinations, availableDestinations); } finally { // Semaphore is released while still holding the lock to AVOID the following case. // The first thread (T1) finished a rebuild and left the lock while still holding the semaphore. The second thread (T2) // waiting on the lock gets awaken, proceeds under the lock and begins the next rebuild. If at this exact moment // the third thread (T3) enters this method and tries to acquire the semaphore, it will be debounced because // the semaphore's count is still 0. However, T2 could have already made some progress and didnt' observe updates made // by T3. // By releasing the semaphore under the lock, we make sure that in the above situation T3 will proceed till the lock and // its updates will be observed anyways. updateLock.Release(); } } }
public DestinationState?PickDestination(HttpContext context, ClusterState cluster, IReadOnlyList <DestinationState> availableDestinations) { if (availableDestinations.Count == 0) { return(null); } var random = _randomFactory.CreateRandomInstance(); return(availableDestinations[random.Next(availableDestinations.Count)]); }
public Task <bool> Handle(HttpContext context, ClusterState cluster, AffinityStatus affinityStatus) { if (affinityStatus == AffinityStatus.OK || affinityStatus == AffinityStatus.AffinityKeyNotSet) { throw new InvalidOperationException($"{nameof(Return503ErrorAffinityFailurePolicy)} is called to handle a successful request's affinity status {affinityStatus}."); } context.Response.StatusCode = 503; return(TaskUtilities.FalseTask); }
public void UpdateAvailableDestinations(ClusterState cluster) { var allDestinations = cluster.DestinationsState?.AllDestinations; if (allDestinations == null) { throw new InvalidOperationException($"{nameof(UpdateAllDestinations)} must be called first."); } UpdateInternal(cluster, allDestinations, force: false); }
public void SetActive(ClusterState cluster, IEnumerable <NewActiveDestinationHealth> newHealthStates) { foreach (var newHealthState in newHealthStates) { newHealthState.Destination.Health.Active = newHealthState.NewActiveHealth; } var destinations = cluster.Destinations.Values.ToList(); cluster.DestinationsState = new ClusterDestinationsState(destinations, destinations); }
private static ClusterState CreateCluster(string id, params DestinationState[] destinations) { var cluster = new ClusterState(id); foreach (var destination in destinations) { cluster.Destinations.TryAdd(destination.DestinationId, destination); } return(cluster); }
private async Task ProbeCluster(ClusterState cluster) { var config = cluster.Model.Config.HealthCheck?.Active; if (config == null || !config.Enabled.GetValueOrDefault()) { return; } Log.StartingActiveHealthProbingOnCluster(_logger, cluster.ClusterId); var allDestinations = cluster.DestinationsState.AllDestinations; var probeTasks = new Task <DestinationProbingResult> [allDestinations.Count]; var probeResults = new DestinationProbingResult[probeTasks.Length]; var timeout = config.Timeout ?? _monitorOptions.DefaultTimeout; for (var i = 0; i < probeTasks.Length; i++) { probeTasks[i] = ProbeDestinationAsync(cluster, allDestinations[i], timeout); } for (var i = 0; i < probeResults.Length; i++) { probeResults[i] = await probeTasks[i]; } try { var policy = _policies.GetRequiredServiceById(config.Policy, HealthCheckConstants.ActivePolicy.ConsecutiveFailures); policy.ProbingCompleted(cluster, probeResults); } catch (Exception ex) { Log.ActiveHealthProbingFailedOnCluster(_logger, cluster.ClusterId, ex); } finally { try { foreach (var probeResult in probeResults) { probeResult.Response?.Dispose(); } } catch (Exception ex) { Log.ErrorOccuredDuringActiveHealthProbingShutdownOnCluster(_logger, cluster.ClusterId, ex); } Log.StoppedActiveHealthProbingOnCluster(_logger, cluster.ClusterId); } }
internal ClusterState GetCluster() { var cluster = new ClusterState("cluster-1"); var destinationManager = cluster.Destinations; destinationManager.GetOrAdd("dest-A", id => new DestinationState(id)); destinationManager.GetOrAdd(AffinitizedDestinationName, id => new DestinationState(id)); destinationManager.GetOrAdd("dest-C", id => new DestinationState(id)); cluster.Model = ClusterConfig; cluster.DestinationsState = new ClusterDestinationsState(destinationManager.Values.ToList(), destinationManager.Values.ToList()); return(cluster); }
protected Cluster(Uri resourceName, ClusterState state) { Name = resourceName; State = state; }
public Cluster RemovePoint(int touchId) { _pointsIds.Remove(touchId); _points.Remove(touchId); UpdateCentroid(); if (State == ClusterState.Identidied || State == ClusterState.Updated) { _state = ClusterState.Cancelled; _cancelledHash = this._hashId; _cancelledPointsIds.Add(touchId); } else if (State == ClusterState.Cancelled) _cancelledPointsIds.Add(touchId); else if (_pointsIds.Count == 4) _state = ClusterState.Unidentified; else _state = ClusterState.Invalid; this._hashId = GetPointsHash(_pointsIds.ToArray<int>()); return this; }
/// <summary> /// Initializes a new instance of the ClusterProvisioningStatusEventArgs class. /// </summary> /// <param name="clusterDetails">Details of the cluster being provisioned.</param> /// <param name="clusterState">Current state of the cluster.</param> public ClusterProvisioningStatusEventArgs(ClusterDetails clusterDetails, ClusterState clusterState) { this.Cluster = clusterDetails; this.State = clusterState; }
/// <summary> /// Cretaes a Cluster instance from a list of List of InputTouch /// </summary> /// <param name="touchPoints"></param> public Cluster(List<TouchInput> touchPoints) { foreach (TouchInput t in touchPoints) { _pointsIds.Add(t.Id); _points.Add(t.Id, t); } UpdateCentroid(); this._hashId = GetPointsHash(_pointsIds.ToArray<int>()); if (_pointsIds.Count == 4) //It is a new cluster of 4 points and requires to be identified this._state = ClusterState.Unidentified; else this._state = ClusterState.Invalid; }
public Cluster[] UpdatePoint(int touchId) { Cluster newCluster; if (Vector2.Distance(this.Centroid, InternalTouches.List[touchId].Position) < ClusterManager.Instance.ClusterDistThreshold) { //Point still in clustrer _points[touchId] = new TouchInput(touchId, InternalTouches.List[touchId].Position, TouchState.Moved); newCluster = null; if (State == ClusterState.Identidied) _state = ClusterState.Updated; } else { //Point has moved out of the cluster //Handle current Cluster //If it was just one point then we must cancel the cluster!!!!!! // if (_pointsIds.Count != 1) // { _pointsIds.Remove(touchId); _points.Remove(touchId); if (_state == ClusterState.Identidied || _state == ClusterState.Updated) { _state = ClusterState.Cancelled; _cancelledHash = this._hashId; _cancelledPointsIds.Add(touchId); } else if (State == ClusterState.Cancelled) _cancelledPointsIds.Add(touchId); else if (_pointsIds.Count == 4) _state = ClusterState.Unidentified; else _state = ClusterState.Invalid; //Update new Hash this._hashId = GetPointsHash(_pointsIds.ToArray<int>()); // } // else newCluster = new Cluster(InternalTouches.List[touchId]); } UpdateCentroid(); return new Cluster[] { this, newCluster }; }
public Cluster AddPoint(int touchId) { TouchInput touch = new TouchInput(touchId, InternalTouches.List[touchId].Position, InternalTouches.List[touchId].State); _pointsIds.Add(touchId); _points.Add(touchId, touch); UpdateCentroid(); this._hashId = GetPointsHash(_pointsIds.ToArray<int>()); if (_pointsIds.Count == 4) this._state = ClusterState.Unidentified; else if (_pointsIds.Count > 4) this._state = ClusterState.Invalid; return this; }
public void SetState(ClusterState newState) { this._state = newState; }
/// <summary> /// Close all resources related to the cluster. Attempts to do so in a graceful manner, flushing /// </summary> /// <param name="timeout"></param> /// <returns></returns> public async Task CloseAsync(TimeSpan timeout) { if (_state == ClusterState.Disconnected || _state == ClusterState.Closed) return; _log.Info("#{0} Closing...", _id); EtwTrace.Log.ClusterStopping(_id); // wait on the partition recovery monitor and all of the correlation loops to shut down. var success = await await Scheduler.Ask(async () => await CloseAsyncImpl().TimeoutAfter(timeout) ).ConfigureAwait(false); if (!success) { _log.Error("Timed out"); EtwTrace.Log.ClusterError(_id, "Timeout on close"); if (!_partitionRecoveryMonitor.Completion.IsCompleted) _log.Error("_partitionRecoveryMonitor timed out"); } else { _log.Info("#{0} Closed", _id); EtwTrace.Log.ClusterStopped(_id); } Scheduler.Dispose(); _state = ClusterState.Disconnected; }
/// <summary> /// Connect to the cluster. Connects to all seed addresses, and fetches initial metadata for the cluster. /// </summary> /// <returns></returns> public async Task ConnectAsync() { await await Scheduler.Ask(async () => { // we cannot reconnect if we have closed already. if (_state == ClusterState.Closed) throw new BrokerException("Cluster is already closed. Cannot reconnect. Please create a new Cluster."); if (_state != ClusterState.Disconnected) return; _log.Debug("Connecting"); var initBrokers = Connection.ParseAddress(_seedBrokers). Select(seed => new BrokerMeta { Host = seed.Item1, Port = seed.Item2, NodeId = -99 }).ToArray(); EtwTrace.Log.ClusterStarting(_id); var initMeta = new MetadataResponse { Topics = new TopicMeta[0], Brokers = initBrokers }; MergeTopicMeta(initMeta); _state = ClusterState.Connected; // start up a recovery monitor to watch for recovered partitions _partitionRecoveryMonitor = new PartitionRecoveryMonitor(this, _protocol, _cancel.Token); // Merge metadata that recovery monitor discovers _partitionRecoveryMonitor.NewMetadataEvents.Subscribe(MergeTopicMeta, ex => _log.Error(ex, "Error thrown by RecoveryMonitor.NewMetadataEvents!")); _log.Debug("Connected"); EtwTrace.Log.ClusterStarted(_id); }).ConfigureAwait(false); }
/// <summary> /// ConnectAsync and fetch list of brokers and metadata. /// </summary> /// <param name="seedBrokers">Comma separated list of seed brokers. Port numbers are optional. /// <example>192.168.56.10,192.168.56.20:8081,broker3.local.net:8181</example> /// </param> public Cluster(string seedBrokers) : this() { _seedBrokers = seedBrokers; _protocol = new Protocol(this); _state = ClusterState.Disconnected; }
internal void ChangeState(ClusterState newState) { this.StateString = newState.ToString(); this.State = newState; }
public byte SetClusterState(int clusterIndex, ClusterState state) { int firstBitIndex = clusterIndex * 2; bool firstBit; bool secondBit; switch (state) { case ClusterState.Free: firstBit = false; secondBit = false; break; case ClusterState.Bad1: firstBit = false; secondBit = true; break; case ClusterState.Bad2: firstBit = true; secondBit = false; break; case ClusterState.Used: firstBit = true; secondBit = true; break; default: firstBit = false; secondBit = false; break; } _bits[firstBitIndex] = firstBit; _bits[firstBitIndex + 1] = secondBit; return (byte)state; }