public override void Start0() { /* * We will start hazelcast in its own thread. Hazelcast blocks until the minimum cluster size is available * and during that block it ignores interrupts. This blocks the whole startup process and since it is the * main thread that controls lifecycle and the main thread is not daemon, it will block ignoring signals * and any shutdown attempts. The solution is to start hazelcast instance creation in its own thread which * we set as daemon. All subsequent uses of hazelcastInstance in this class will still block on it being * available (see waitOnHazelcastInstanceCreation() ) but they do so while checking for interrupt and * exiting if one happens. This provides us with a way to exit before hazelcastInstance creation completes. */ _startingThread = new Thread(() => { Log.info("Cluster discovery service starting"); _hazelcastInstance = CreateHazelcastInstance(); // We may be interrupted by the stop method after hazelcast returns. This is courtesy and not really // necessary if (Thread.CurrentThread.Interrupted) { return; } _refreshJob = _scheduler.scheduleRecurring(Group.HZ_TOPOLOGY_REFRESH, _refreshPeriod, HazelcastCoreTopologyService.this.refreshTopology); Log.info("Cluster discovery service started"); }); _startingThread.Daemon = true; _startingThread.Name = "HZ Starting Thread"; _startingThread.Start(); }
internal static IDictionary <MemberId, ReadReplicaInfo> ReadReplicas(HazelcastInstance hazelcastInstance, Log log) { Pair <ISet <string>, IDictionary <string, IMap <string, string> > > validatedSimpleAttrMaps = validatedSimpleAttrMaps(hazelcastInstance); ISet <string> missingAttrKeys = validatedSimpleAttrMaps.First(); IDictionary <string, IMap <string, string> > simpleAttrMaps = validatedSimpleAttrMaps.Other(); MultiMap <string, string> serverGroupsMap = hazelcastInstance.getMultiMap(SERVER_GROUPS_MULTIMAP); if (serverGroupsMap == null) { missingAttrKeys.Add(SERVER_GROUPS_MULTIMAP); } if (missingAttrKeys.Count > 0) { // We might well not have any read replicas, in which case missing maps is not an error, but we *can't* have some maps and not others //JAVA TO C# CONVERTER TODO TASK: There is no .NET equivalent to the java.util.Collection 'containsAll' method: bool missingAllKeys = missingAttrKeys.containsAll(RrAttrKeys) && missingAttrKeys.Contains(SERVER_GROUPS_MULTIMAP); if (!missingAllKeys) { string missingAttrs = string.join(", ", missingAttrKeys); log.Warn("Some, but not all, of the read replica attribute maps are null, including %s", missingAttrs); } return(emptyMap()); } Stream <string> readReplicaHzIds = simpleAttrMaps[READ_REPLICA_BOLT_ADDRESS_MAP].Keys.stream(); //JAVA TO C# CONVERTER TODO TASK: Method reference arbitrary object instance method syntax is not converted by Java to C# Converter: IDictionary <MemberId, ReadReplicaInfo> validatedReadReplicas = readReplicaHzIds.flatMap(hzId => Streams.ofNullable(BuildReadReplicaFromAttrMap(hzId, simpleAttrMaps, serverGroupsMap, log))).collect(Collectors.toMap(Pair::first, Pair::other)); return(validatedReadReplicas); }
internal static void CasLeaders(HazelcastInstance hazelcastInstance, LeaderInfo leaderInfo, string dbName, Log log) { IAtomicReference <LeaderInfo> leaderRef = hazelcastInstance.getAtomicReference(DB_NAME_LEADER_TERM_PREFIX + dbName); LeaderInfo current = leaderRef.get(); Optional <LeaderInfo> currentOpt = Optional.ofNullable(current); //JAVA TO C# CONVERTER TODO TASK: Method reference arbitrary object instance method syntax is not converted by Java to C# Converter: bool sameLeader = currentOpt.map(LeaderInfo::memberId).Equals(Optional.ofNullable(leaderInfo.MemberId())); int termComparison = currentOpt.map(l => Long.compare(l.term(), leaderInfo.Term())).orElse(-1); bool greaterTermExists = termComparison > 0; bool sameTermButNoStepdown = termComparison == 0 && !leaderInfo.SteppingDown; if (sameLeader || greaterTermExists || sameTermButNoStepdown) { return; } bool success = leaderRef.compareAndSet(current, leaderInfo); if (!success) { log.Warn("Fail to set new leader info: %s. Latest leader info: %s.", leaderInfo, leaderRef.get()); } }
internal static bool CasClusterId(HazelcastInstance hazelcastInstance, ClusterId clusterId, string dbName) { IMap <string, System.Guid> uuidPerDbCluster = hazelcastInstance.getMap(CLUSTER_UUID_DB_NAME_MAP); System.Guid uuid = uuidPerDbCluster.putIfAbsent(dbName, clusterId.Uuid()); return(uuid == null || clusterId.Uuid().Equals(uuid)); }
private static ClusterId GetClusterId(HazelcastInstance hazelcastInstance, string dbName) { IMap <string, System.Guid> uuidPerDbCluster = hazelcastInstance.getMap(CLUSTER_UUID_DB_NAME_MAP); System.Guid uuid = uuidPerDbCluster.get(dbName); return(uuid != null ? new ClusterId(uuid) : null); }
public static IDictionary <MemberId, RoleInfo> GetCoreRoles(HazelcastInstance hazelcastInstance, ISet <MemberId> coreMembers) { ISet <string> dbNames = GetDBNames(hazelcastInstance); //JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter: ISet <MemberId> allLeaders = dbNames.Select(n => GetLeaderForDBName(hazelcastInstance, n)).Where(Optional.isPresent).Select(l => l.get().memberId()).collect(Collectors.toSet()); System.Func <MemberId, RoleInfo> roleMapper = m => allLeaders.Contains(m) ? RoleInfo.Leader : RoleInfo.Follower; return(coreMembers.ToDictionary(System.Func.identity(), roleMapper)); }
internal static void RefreshGroups(HazelcastInstance hazelcastInstance, string memberId, IList <string> groups) { MultiMap <string, string> groupsMap = hazelcastInstance.getMultiMap(SERVER_GROUPS_MULTIMAP); ICollection <string> existing = groupsMap.get(memberId); //JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter: ISet <string> superfluous = existing.Where(t => !groups.Contains(t)).collect(Collectors.toSet()); //JAVA TO C# CONVERTER TODO TASK: Most Java stream collectors are not converted by Java to C# Converter: ISet <string> missing = groups.Where(t => !existing.Contains(t)).collect(Collectors.toSet()); missing.forEach(group => groupsMap.put(memberId, group)); superfluous.forEach(group => groupsMap.remove(memberId, group)); }
private static bool CanBeBootstrapped(HazelcastInstance hazelcastInstance, Config config) { ISet <Member> members = hazelcastInstance.Cluster.Members; string dbName = config.Get(CausalClusteringSettings.database); System.Predicate <Member> acceptsToBeLeader = m => !m.getBooleanAttribute(REFUSE_TO_BE_LEADER_KEY); System.Predicate <Member> hostsMyDb = m => dbName.Equals(m.getStringAttribute(MEMBER_DB_NAME)); Stream <Member> membersWhoCanLeadForMyDb = members.Where(acceptsToBeLeader).Where(hostsMyDb); Optional <Member> firstAppropriateMember = membersWhoCanLeadForMyDb.findFirst(); return(firstAppropriateMember.map(Member.localMember).orElse(false)); }
internal static ReadReplicaTopology GetReadReplicaTopology(HazelcastInstance hazelcastInstance, Log log) { IDictionary <MemberId, ReadReplicaInfo> readReplicas = emptyMap(); if (hazelcastInstance != null) { readReplicas = readReplicas(hazelcastInstance, log); } else { log.Info("Cannot currently bind to distributed discovery service."); } return(new ReadReplicaTopology(readReplicas)); }
internal static CoreTopology GetCoreTopology(HazelcastInstance hazelcastInstance, Config config, Log log) { IDictionary <MemberId, CoreServerInfo> coreMembers = emptyMap(); bool canBeBootstrapped = false; ClusterId clusterId = null; string dbName = config.Get(CausalClusteringSettings.database); if (hazelcastInstance != null) { ISet <Member> hzMembers = hazelcastInstance.Cluster.Members; canBeBootstrapped = canBeBootstrapped(hazelcastInstance, config); coreMembers = ToCoreMemberMap(hzMembers, log, hazelcastInstance); clusterId = GetClusterId(hazelcastInstance, dbName); } else { log.Info("Cannot currently bind to distributed discovery service."); } return(new CoreTopology(clusterId, canBeBootstrapped, coreMembers)); }
private HazelcastInstance CreateHazelcastInstance() { JoinConfig joinConfig = new JoinConfig(); joinConfig.MulticastConfig.Enabled = false; TcpIpConfig tcpIpConfig = joinConfig.TcpIpConfig; tcpIpConfig.Enabled = true; //JAVA TO C# CONVERTER TODO TASK: Method reference arbitrary object instance method syntax is not converted by Java to C# Converter: ICollection <string> initialMembers = _remoteMembersResolver.resolve(SocketAddress::toString); initialMembers.forEach(tcpIpConfig.addMember); ListenSocketAddress hazelcastAddress = Config.get(discovery_listen_address); NetworkConfig networkConfig = new NetworkConfig(); if (!hazelcastAddress.Wildcard) { InterfacesConfig interfaces = new InterfacesConfig(); interfaces.addInterface(hazelcastAddress.Hostname); interfaces.Enabled = true; networkConfig.Interfaces = interfaces; } networkConfig.Port = hazelcastAddress.Port; networkConfig.Join = joinConfig; networkConfig.PortAutoIncrement = false; // We'll use election_timeout as a base value to calculate HZ timeouts. We multiply by 1.5 long?electionTimeoutMillis = Config.get(CausalClusteringSettings.leader_election_timeout).toMillis(); long?baseHazelcastTimeoutMillis = (3 * electionTimeoutMillis) / 2; /* * Some HZ settings require the value in seconds. Adding the divider and subtracting 1 is equivalent to the * ceiling function for integers ( Math.ceil() returns double ). Anything < 0 will return 0, any * multiple of 1000 returns the result of the division by 1000, any non multiple of 1000 returns the result * of the division + 1. In other words, values in millis are rounded up. */ long baseHazelcastTimeoutSeconds = (baseHazelcastTimeoutMillis + 1000 - 1) / 1000; com.hazelcast.config.Config c = new com.hazelcast.config.Config(); c.setProperty(OPERATION_CALL_TIMEOUT_MILLIS.Name, baseHazelcastTimeoutMillis.ToString()); c.setProperty(MERGE_NEXT_RUN_DELAY_SECONDS.Name, baseHazelcastTimeoutSeconds.ToString()); c.setProperty(MERGE_FIRST_RUN_DELAY_SECONDS.Name, baseHazelcastTimeoutSeconds.ToString()); c.setProperty(INITIAL_MIN_CLUSTER_SIZE.Name, HAZELCAST_MIN_CLUSTER.ToString()); if (Config.get(disable_middleware_logging)) { c.setProperty(LOGGING_TYPE.Name, "none"); } if (hazelcastAddress.IPv6) { c.setProperty(PREFER_IPv4_STACK.Name, "false"); } c.NetworkConfig = networkConfig; MemberAttributeConfig memberAttributeConfig = HazelcastClusterTopology.BuildMemberAttributesForCore(MyselfConflict, Config); c.MemberAttributeConfig = memberAttributeConfig; LogConnectionInfo(initialMembers); c.addListenerConfig(new ListenerConfig(new OurMembershipListener(this))); JobHandle logJob = _scheduler.schedule(Group.HZ_TOPOLOGY_HEALTH, _hazelcastIsHealthyTimeoutMs, () => Log.warn("The server has not been able to connect in a timely fashion to the " + "cluster. Please consult the logs for more details. Rebooting the server may " + "solve the problem.")); try { _hazelcastInstance = Hazelcast.newHazelcastInstance(c); logJob.Cancel(true); } catch (HazelcastException e) { string errorMessage = string.Format("Hazelcast was unable to start with setting: {0} = {1}", discovery_listen_address.name(), Config.get(discovery_listen_address)); UserLog.error(errorMessage); Log.error(errorMessage, e); throw new Exception(e); } IList <string> groups = Config.get(CausalClusteringSettings.server_groups); refreshGroups(_hazelcastInstance, MyselfConflict.Uuid.ToString(), groups); return(_hazelcastInstance); }
internal static IDictionary <MemberId, CoreServerInfo> ToCoreMemberMap(ISet <Member> members, Log log, HazelcastInstance hazelcastInstance) { IDictionary <MemberId, CoreServerInfo> coreMembers = new Dictionary <MemberId, CoreServerInfo>(); MultiMap <string, string> serverGroupsMMap = hazelcastInstance.getMultiMap(SERVER_GROUPS_MULTIMAP); foreach (Member member in members) { IDictionary <string, string> attrMap = new Dictionary <string, string>(); bool incomplete = false; foreach (string attrKey in CoreAttrKeys) { string attrValue = member.getStringAttribute(attrKey); if (string.ReferenceEquals(attrValue, null)) { log.Warn("Missing member attribute '%s' for member %s", attrKey, member); incomplete = true; } else { attrMap[attrKey] = attrValue; } } if (incomplete) { continue; } //JAVA TO C# CONVERTER TODO TASK: Method reference constructor syntax is not converted by Java to C# Converter: CoreServerInfo coreServerInfo = new CoreServerInfo(socketAddress(attrMap[RAFT_SERVER], AdvertisedSocketAddress::new), socketAddress(attrMap[TRANSACTION_SERVER], AdvertisedSocketAddress::new), ClientConnectorAddresses.FromString(attrMap[CLIENT_CONNECTOR_ADDRESSES]), asSet(serverGroupsMMap.get(attrMap[MEMBER_UUID])), attrMap[MEMBER_DB_NAME], member.getBooleanAttribute(REFUSE_TO_BE_LEADER_KEY)); MemberId memberId = new MemberId(System.Guid.Parse(attrMap[MEMBER_UUID])); coreMembers[memberId] = coreServerInfo; } return(coreMembers); }
private static Optional <LeaderInfo> GetLeaderForDBName(HazelcastInstance hazelcastInstance, string dbName) { IAtomicReference <LeaderInfo> leader = hazelcastInstance.getAtomicReference(DB_NAME_LEADER_TERM_PREFIX + dbName); return(Optional.ofNullable(leader.get())); }
/// <summary> /// Retrieves the various maps containing attributes about read replicas from hazelcast. If any maps do not exist, keep track of their keys for logging. /// </summary> private static Pair <ISet <string>, IDictionary <string, IMap <string, string> > > ValidatedSimpleAttrMaps(HazelcastInstance hazelcastInstance) { ISet <string> missingAttrKeys = new HashSet <string>(); IDictionary <string, IMap <string, string> > validatedSimpleAttrMaps = new Dictionary <string, IMap <string, string> >(); foreach (string attrMapKey in RrAttrKeys) { IMap <string, string> attrMap = hazelcastInstance.getMap(attrMapKey); if (attrMap == null) { missingAttrKeys.Add(attrMapKey); } else { validatedSimpleAttrMaps[attrMapKey] = attrMap; } } return(Pair.of(missingAttrKeys, validatedSimpleAttrMaps)); }
private static ISet <string> GetDBNames(HazelcastInstance hazelcastInstance) { IMap <string, System.Guid> uuidPerDbCluster = hazelcastInstance.getMap(CLUSTER_UUID_DB_NAME_MAP); return(uuidPerDbCluster.Keys); }