public async Task KeepPollingForLeaderInfo(CancellationToken token) { while (!token.IsCancellationRequested) { try { var info = await LeaderInfo.Get(_storage); if (info == null) { _cloudClient = null; await Task.Delay(500, token); continue; } var newEndpoint = info.GetEndpoint(); if (_endpoint != newEndpoint) { Log.Information("Detected new leader {endpoint}", newEndpoint); _endpoint = newEndpoint; var password = _storage.GetSysPassword(); _cloudClient = new CloudClient(_endpoint, Constants.ClusterNodeUser, password); } await Task.Delay(3500, token); } catch (StorageException ex) { Log.Warning(ex, "Failed to refresh leader info"); token.WaitHandle.WaitOne(1000); } } }
public static App Initialize(AppConfig config, Func<StartOptions, NancyOptions, IDisposable> hostFunc) { config.ThrowIfInvalid(); var poller = new LeaderInfoPoller(config.StorageAccount); var startOptions = new StartOptions(); startOptions.Urls.Add(config.InternalUri); startOptions.Urls.Add(config.PublicUri); var auth = LoadAuth.LoadFromStorageAccount(config.StorageAccount); AddSystemAccess(auth, config.StorageAccount.GetSysPassword()); var api = ApiImplementation.Create(config.StorageAccount, poller, auth); var nancyOptions = new NancyOptions { Bootstrapper = new NancyBootstrapper(api, new UserValidator(auth)) }; var nodeInfo = new LeaderInfo(config.InternalUri); var selector = new LeaderLock(config.StorageAccount, nodeInfo, api); var cts = new CancellationTokenSource(); // fire up leader and scheduler first var tasks = new List<Task> { selector.KeepTryingToAcquireLock(cts.Token), poller.KeepPollingForLeaderInfo(cts.Token), }; // bind the API var host = hostFunc(startOptions, nancyOptions); return new App(host, cts, tasks); }
public LeaderLock(ICloudFactory account, LeaderInfo info, ApiImplementation api) { Require.NotNull("account", account); Require.NotNull("info", info); _account = account; _info = info; _api = api; _lease = RenewableBlobLease.Create(account, LeaderMethod); }