func Announce(localIP string, ttl time.Duration, config *config.Config, storeAdapter storeadapter.StoreAdapter, logger *gosteno.Logger) chan (chan bool) { dopplerMetaBytes, err := buildDopplerMeta(localIP, config) if err != nil { panic(err) } key := fmt.Sprintf("%s/%s/%s/%d", META_ROOT, config.Zone, config.JobName, config.Index) logger.Debugf("Starting Health Status Updates to Store: %s", key) node := storeadapter.StoreNode{ Key: key, Value: dopplerMetaBytes, TTL: uint64(ttl.Seconds()), } // Call to create to make sure node is created before we return storeAdapter.Create(node) status, stopChan, err := storeAdapter.MaintainNode(node) if err != nil { panic(err) } // The status channel needs to be drained to maintain the node within the etcd cluster go func() { for stat := range status { logger.Debugf("Health updates channel pushed %v at time %v", stat, time.Now()) } }() return stopChan }
func AddETCDNode(etcdAdapter storeadapter.StoreAdapter, key string, value string) { node := storeadapter.StoreNode{ Key: key, Value: []byte(value), TTL: uint64(20), } etcdAdapter.Create(node) recvNode, err := etcdAdapter.Get(key) Expect(err).NotTo(HaveOccurred()) Expect(string(recvNode.Value)).To(Equal(value)) }
finder.Stop() }) getCallbackCount := func() int { return int(atomic.LoadInt32(callbackCount)) } getPreferredCount := func() int { return int(atomic.LoadInt32(preferredCount)) } testUpdateFinder := func(updatedAddress map[string]string) func() { return func() { Context("when a service exists", func() { JustBeforeEach(func() { err := storeAdapter.Create(node) Expect(err).NotTo(HaveOccurred()) finder.Start() Eventually(finder.AllServers).ShouldNot(HaveLen(0)) Expect(finder.PreferredServers()).NotTo(HaveLen(0)) }) It("updates the service", func() { err := storeAdapter.Update(updateNode) Expect(err).NotTo(HaveOccurred()) Eventually(finder.AllServers).Should(Equal(updatedAddress)) Expect(getCallbackCount()).To(Equal(2)) Expect(finder.PreferredServers()).To(Equal(updatedAddress)) Expect(getPreferredCount()).To(Equal(2))
}) }) Describe("Loading listener state on startup", func() { Context("when the store is empty", func() { It("should not send anything on the output channels", func() { go listener.Run() assertNoDataOnChannel(outAddChan) assertNoDataOnChannel(outRemoveChan) }) }) Context("when the store has AppServices in it", func() { BeforeEach(func() { adapter.Create(buildNode(app1Service1)) adapter.Create(buildNode(app1Service2)) adapter.Create(buildNode(app2Service1)) }) It("should send all the AppServices on the output add channel", func(done Done) { go listener.Run() appServices := drainOutgoingChannel(outAddChan, 3) Expect(appServices).To(ContainElement(app1Service1)) Expect(appServices).To(ContainElement(app1Service2)) Expect(appServices).To(ContainElement(app2Service1)) assertNoDataOnChannel(outRemoveChan)