private async Task Run()
        {
            availableNodes = RangeServicesToDictionary(await etcdClient.GetRange("heartbeat"));

            watcher = await etcdClient.WatchRange("heartbeat");

            watcher.Subscribe(events =>
            {
                foreach (var e in events)
                {
                    var service = DiscoverableService.CreateFromEtcdKey(e.Key);
                    switch (e.Type)
                    {
                    case EventType.Put:
                        IList <DiscoverableService> values;
                        if (availableNodes.TryGetValue(service.Type, out values))
                        {
                            values.Add(service);
                        }
                        else
                        {
                            availableNodes.Add(service.Type, new List <DiscoverableService> {
                                service
                            });
                        }
                        break;

                    case EventType.Delete:
                        var valuesForKey = availableNodes[service.Type];
                        var isDeleted    = valuesForKey.Remove(service);
                        if (!isDeleted)
                        {
                            throw new Exception("This can not happen");
                        }
                        if (!valuesForKey.Any())
                        {
                            availableNodes.Remove(e.Key);
                        }
                        break;
                    }
                }
                Console.WriteLine($"Available nodes {availableNodes.Aggregate(string.Empty, (acc, item) => $"{item.Key} - {item.Value.Aggregate(string.Empty, (a, i) => $"{i.Address} {a}")} {acc}")}");
            });
        }
 WatchValues(ConcurrentDictionary <string, List <string> > cd)
 {
     try
     {
         var dk = etcdClient.GetRange(conf).Result;
         foreach (var item in dk)
         {
             cd.AddOrUpdate(item.Key.Replace(conf, ""), new List <string> {
                 item.Value
             }, (key, value) =>
             {
                 value[0] = item.Value;
                 return(value);
             });
         }
     }
     catch
     {
         foreach (var item in cd)
         {
             await etcdClient.Put(conf + item.Key, item.Value[0]);
         }
     }
     watcher = etcdClient.WatchRange(conf).Result;
     watcher.Subscribe(s =>
     {
         foreach (var item in s)
         {
             cd.AddOrUpdate(item.Key.Replace(conf, ""), new List <string> {
                 item.Value
             }, (key, value) =>
             {
                 value[0] = item.Value;
                 return(value);
             });
         }
     });
 }