func (registry *Registry) Register(uri route.Uri, endpoint *route.Endpoint) { registry.Lock() defer registry.Unlock() uri = uri.ToLower() key := tableKey{ addr: endpoint.CanonicalAddr(), uri: uri, } var endpointToRegister *route.Endpoint entry, found := registry.table[key] if found { endpointToRegister = entry.endpoint } else { endpointToRegister = endpoint entry = &tableEntry{endpoint: endpoint} registry.table[key] = entry } pool, found := registry.byUri[uri] if !found { pool = route.NewPool() registry.byUri[uri] = pool } pool.Add(endpointToRegister) entry.updatedAt = time.Now() registry.timeOfLastUpdate = time.Now() }
func (r *Trie) Insert(uri route.Uri, value *route.Pool) *Trie { key := strings.TrimPrefix(uri.String(), "/") node := r for { pathParts := parts(key) SegmentValue := pathParts[0] matchingChild, ok := node.ChildNodes[SegmentValue] if !ok { matchingChild = NewTrie() matchingChild.Segment = SegmentValue matchingChild.Parent = node node.ChildNodes[SegmentValue] = matchingChild } node = matchingChild if len(pathParts) != 2 { break } key = pathParts[1] } node.Pool = value return node }
func (r *RouteRegistry) Register(uri route.Uri, endpoint *route.Endpoint) { t := time.Now() data := lager.Data{"uri": uri, "backend": endpoint.CanonicalAddr(), "modification_tag": endpoint.ModificationTag} r.reporter.CaptureRegistryMessage(endpoint) r.Lock() uri = uri.RouteKey() pool, found := r.byUri.Find(uri) if !found { contextPath := parseContextPath(uri) pool = route.NewPool(r.dropletStaleThreshold/4, contextPath) r.byUri.Insert(uri, pool) r.logger.Debug("uri-added", lager.Data{"uri": uri}) } endpointAdded := pool.Put(endpoint) r.timeOfLastUpdate = t r.Unlock() if endpointAdded { r.logger.Debug("endpoint-registered", data) } else { r.logger.Debug("endpoint-not-registered", data) } }
func (r *Trie) Delete(uri route.Uri) bool { key := strings.TrimPrefix(uri.String(), "/") node := r initialKey := key for { pathParts := parts(key) SegmentValue := pathParts[0] // It is currently impossible to Delete a non-existent path. This invariant is // provided by the fact that a call to Find is done before Delete in the registry. matchingChild, _ := node.ChildNodes[SegmentValue] node = matchingChild if len(pathParts) <= 1 { break } key = pathParts[1] } node.Pool = nil r.deleteEmptyNodes(initialKey) return true }
func (r *Trie) Find(uri route.Uri) (*route.Pool, bool) { key := strings.TrimPrefix(uri.String(), "/") node := r for { pathParts := parts(key) SegmentValue := pathParts[0] matchingChild, ok := node.ChildNodes[SegmentValue] if !ok { return nil, false } node = matchingChild if len(pathParts) <= 1 { break } key = pathParts[1] } if nil != node.Pool { return node.Pool, true } return nil, false }
func parseContextPath(uri route.Uri) string { contextPath := "/" split := strings.SplitN(strings.TrimPrefix(uri.String(), "/"), "/", 2) if len(split) > 1 { contextPath += split[1] } return contextPath }
func (r *RouteRegistry) Lookup(uri route.Uri) *route.Pool { r.RLock() uri = uri.ToLower() pool := r.byUri[uri] r.RUnlock() return pool }
func (registry *Registry) Unregister(uri route.Uri, endpoint *route.Endpoint) { registry.Lock() defer registry.Unlock() uri = uri.ToLower() key := tableKey{ addr: endpoint.CanonicalAddr(), uri: uri, } registry.unregisterUri(key) }
func (r *RouteRegistry) Lookup(uri route.Uri) *route.Pool { r.RLock() uri = uri.RouteKey() var err error pool, found := r.byUri.MatchUri(uri) for !found && err == nil { uri, err = uri.NextWildcard() pool, found = r.byUri.MatchUri(uri) } r.RUnlock() return pool }
func (r *RouteRegistry) Unregister(uri route.Uri, endpoint *route.Endpoint) { r.Lock() uri = uri.RouteKey() pool, found := r.byUri.Find(uri) if found { pool.Remove(endpoint) if pool.IsEmpty() { r.byUri.Delete(uri) } } r.Unlock() }
func (r *RouteRegistry) Unregister(uri route.Uri, endpoint *route.Endpoint) { r.Lock() uri = uri.ToLower() pool, found := r.byUri[uri] if found { pool.Remove(endpoint) if pool.IsEmpty() { delete(r.byUri, uri) } } r.Unlock() }
func (r *RouteRegistry) Register(uri route.Uri, endpoint *route.Endpoint) { t := time.Now() r.Lock() uri = uri.ToLower() pool, found := r.byUri[uri] if !found { pool = route.NewPool(r.dropletStaleThreshold / 4) r.byUri[uri] = pool } pool.Put(endpoint) r.timeOfLastUpdate = t r.Unlock() }
func (r *RouteRegistry) Register(uri route.Uri, endpoint *route.Endpoint) { t := time.Now() r.Lock() uri = uri.RouteKey() pool, found := r.byUri.Find(uri) if !found { contextPath := parseContextPath(uri) pool = route.NewPool(r.dropletStaleThreshold/4, contextPath) r.byUri.Insert(uri, pool) } pool.Put(endpoint) r.timeOfLastUpdate = t r.Unlock() }
func (r *RouteRegistry) Unregister(uri route.Uri, endpoint *route.Endpoint) { r.reporter.CaptureRegistryMessage(endpoint) r.Lock() uri = uri.RouteKey() pool, found := r.byUri.Find(uri) if found { pool.Remove(endpoint) if pool.IsEmpty() { r.byUri.Delete(uri) } r.logger.Debug("unregister", lager.Data{"uri": uri}) } r.Unlock() }
func (r *RouteRegistry) Register(uri route.Uri, endpoint *route.Endpoint) { t := time.Now() r.reporter.CaptureRegistryMessage(endpoint) r.Lock() uri = uri.RouteKey() pool, found := r.byUri.Find(uri) if !found { contextPath := parseContextPath(uri) pool = route.NewPool(r.dropletStaleThreshold/4, contextPath) r.byUri.Insert(uri, pool) r.logger.Debug("register", lager.Data{"uri": uri}) } pool.Put(endpoint) r.timeOfLastUpdate = t r.Unlock() }
func (r *RouteRegistry) Unregister(uri route.Uri, endpoint *route.Endpoint) { data := lager.Data{"uri": uri, "backend": endpoint.CanonicalAddr(), "modification_tag": endpoint.ModificationTag} r.reporter.CaptureRegistryMessage(endpoint) r.Lock() uri = uri.RouteKey() pool, found := r.byUri.Find(uri) if found { endpointRemoved := pool.Remove(endpoint) if endpointRemoved { r.logger.Debug("endpoint-unregistered", data) } else { r.logger.Debug("endpoint-not-unregistered", data) } if pool.IsEmpty() { r.byUri.Delete(uri) } } r.Unlock() }
package route_test import ( "github.com/cloudfoundry/gorouter/route" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" ) var _ = Describe("URIs", func() { Context("RouteKey", func() { var key route.Uri It("creates a route key based on uri", func() { key = route.Uri("dora.app.com").RouteKey() Expect(key.String()).To(Equal("dora.app.com")) key = route.Uri("dora.app.com/").RouteKey() Expect(key.String()).To(Equal("dora.app.com")) key = route.Uri("dora.app.com/v1").RouteKey() Expect(key.String()).To(Equal("dora.app.com/v1")) }) Context("has a context path", func() { It("creates route key with context path", func() { key = route.Uri("dora.app.com/v1").RouteKey() Expect(key.String()).To(Equal("dora.app.com/v1"))
func (r *Registry) lookupByUri(uri route.Uri) (*route.Pool, bool) { uri = uri.ToLower() pool, ok := r.byUri[uri] return pool, ok }