/// <summary> /// Connect to canal server. /// </summary> /// <returns></returns> public async Task ConnectAsync() { //get canal address from zk await ConnectToZkAsync(); var nodeData = await _zk.GetDataAsync(ZK_SERVER_RUNNING_NODE); var runningInfo = JsonConvert.DeserializeObject <CanalServerRunningInfo>(Encoding.UTF8.GetString(nodeData)); _logger.LogInformation($"get canal address from zookeeper success: {runningInfo.Address}"); //connect to canal _currentConn = new SimpleCanalConnection(CopyOptions(runningInfo), _loggerFactory.CreateLogger <SimpleCanalConnection>()); await _currentConn.ConnectAsync(); _serverRunningNodeReCreated = false; var localIp = _currentConn.GetLocalEndPoint().ToString(); _clientRunningInfo = new CanalClientRunningInfo() { Active = true, Address = localIp, ClientId = _options.ClientId }; _ = GetZkLockAsync(_clientRunningInfo); await _completionSource.Task; _logger.LogInformation("Ready to use!"); }
private async Task GetZkLockAsync(CanalClientRunningInfo runningInfo, bool waiting = false) { var times = 0; while (waiting && times < 60) { await Task.Delay(1000); times++; _logger.LogWarning($"Waiting for get lock {times}-60..."); } if (await _zk.NodeExistsAsync(ZK_CLIENT_RUNNING_NODE)) { _logger.LogInformation($"Node {ZK_CLIENT_RUNNING_NODE} exits, get Zookeeper lock failed. Other instances are running."); _logger.LogWarning("Waiting..."); } else { try { var clientNodeData = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(runningInfo)); var parentNode = ZK_CLIENT_RUNNING_NODE.Replace("/running", ""); if (!await _zk.NodeExistsAsync(parentNode)) { await _zk.CreateNodeAsync(parentNode, null, new List <Acl>() { new Acl(AclPerm.All, AclScheme.World, AclId.World()) }, NodeType.Persistent); } await _zk.CreateNodeAsync(ZK_CLIENT_RUNNING_NODE, clientNodeData, new List <Acl>() { new Acl(AclPerm.All, AclScheme.World, AclId.World()) }, NodeType.Ephemeral); await _zk.CreateNodeAsync(parentNode + "/" + runningInfo.Address, null, new List <Acl>() { new Acl(AclPerm.All, AclScheme.World, AclId.World()) }, NodeType.Ephemeral); await _zk.NodeExistsAsync(ZK_CLIENT_RUNNING_NODE); _completionSource.SetResult(0); _logger.LogInformation("Get zookeeper lock success."); } catch (KeeperException.NodeExistsException e) { if (e.getPath() != ZK_CLIENT_RUNNING_NODE) { _logger.LogError(e, "Error during get lock."); Environment.Exit(-1); } _logger.LogInformation( $"Node {ZK_CLIENT_RUNNING_NODE} exits, get Zookeeper lock failed. Other instances are running."); _logger.LogWarning("Waiting..."); } catch (Exception e) { _logger.LogError(e, "Exception in lock"); } } }