Watcher now emits events instead of results.
This commit is contained in:
		| @@ -253,7 +253,7 @@ func (r *router) watchTable(w Watcher) error { | ||||
|  | ||||
| 	// watch for changes to services | ||||
| 	for { | ||||
| 		res, err := w.Next() | ||||
| 		event, err := w.Next() | ||||
| 		if err == ErrWatcherStopped { | ||||
| 			break | ||||
| 		} | ||||
| @@ -269,21 +269,21 @@ func (r *router) watchTable(w Watcher) error { | ||||
| 		} | ||||
|  | ||||
| 		service := ®istry.Service{ | ||||
| 			Name:  res.Route.Options().DestAddr, | ||||
| 			Name:  event.Route.Options().DestAddr, | ||||
| 			Nodes: []*registry.Node{node}, | ||||
| 		} | ||||
|  | ||||
| 		switch res.Action { | ||||
| 		case "add": | ||||
| 		switch event.Type { | ||||
| 		case CreateEvent: | ||||
| 			// only register remotely if the service is "local" | ||||
| 			if res.Route.Options().Network == "local" { | ||||
| 			if event.Route.Options().Network == "local" { | ||||
| 				if err := r.opts.NetworkRegistry.Register(service, registry.RegisterTTL(120*time.Second)); err != nil { | ||||
| 					return fmt.Errorf("failed to register service %s in network registry: %v", service.Name, err) | ||||
| 				} | ||||
| 			} | ||||
| 		case "delete": | ||||
| 		case UpdateEvent: | ||||
| 			// only deregister remotely if the service is "local" | ||||
| 			if res.Route.Options().Network == "local" { | ||||
| 			if event.Route.Options().Network == "local" { | ||||
| 				if err := r.opts.NetworkRegistry.Deregister(service); err != nil { | ||||
| 					return fmt.Errorf("failed to deregister service %s from network registry: %v", service.Name, err) | ||||
| 				} | ||||
|   | ||||
| @@ -11,8 +11,8 @@ import ( | ||||
| 	"github.com/olekukonko/tablewriter" | ||||
| ) | ||||
|  | ||||
| // TODO: table options TBD in the future | ||||
| // TableOptions are routing table options | ||||
| // TODO: This will allow for arbitrary routing table options in the future | ||||
| type TableOptions struct{} | ||||
|  | ||||
| // table is in memory routing table | ||||
| @@ -74,14 +74,14 @@ func (t *table) Add(r Route) error { | ||||
| 	if _, ok := t.m[destAddr]; !ok { | ||||
| 		t.m[destAddr] = make(map[uint64]Route) | ||||
| 		t.m[destAddr][sum] = r | ||||
| 		go t.sendResult(&Result{Action: "add", Route: r}) | ||||
| 		go t.sendEvent(&Event{Type: CreateEvent, Route: r}) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| 	// only add the route if it exists and if override is requested | ||||
| 	if _, ok := t.m[destAddr][sum]; ok && r.Options().Policy == OverrideIfExists { | ||||
| 		t.m[destAddr][sum] = r | ||||
| 		go t.sendResult(&Result{Action: "update", Route: r}) | ||||
| 		go t.sendEvent(&Event{Type: UpdateEvent, Route: r}) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| @@ -107,7 +107,7 @@ func (t *table) Delete(r Route) error { | ||||
| 	} | ||||
|  | ||||
| 	delete(t.m[destAddr], sum) | ||||
| 	go t.sendResult(&Result{Action: "delete", Route: r}) | ||||
| 	go t.sendEvent(&Event{Type: DeleteEvent, Route: r}) | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
| @@ -128,7 +128,7 @@ func (t *table) Update(r Route) error { | ||||
| 	// if the route has been found update it | ||||
| 	if _, ok := t.m[destAddr][sum]; ok { | ||||
| 		t.m[destAddr][sum] = r | ||||
| 		go t.sendResult(&Result{Action: "update", Route: r}) | ||||
| 		go t.sendEvent(&Event{Type: UpdateEvent, Route: r}) | ||||
| 		return nil | ||||
| 	} | ||||
|  | ||||
| @@ -188,7 +188,7 @@ func (t *table) Watch(opts ...WatchOption) (Watcher, error) { | ||||
|  | ||||
| 	watcher := &tableWatcher{ | ||||
| 		opts:    wopts, | ||||
| 		resChan: make(chan *Result, 10), | ||||
| 		resChan: make(chan *Event, 10), | ||||
| 		done:    make(chan struct{}), | ||||
| 	} | ||||
|  | ||||
| @@ -199,8 +199,8 @@ func (t *table) Watch(opts ...WatchOption) (Watcher, error) { | ||||
| 	return watcher, nil | ||||
| } | ||||
|  | ||||
| // sendResult sends rules to all subscribe watchers | ||||
| func (t *table) sendResult(r *Result) { | ||||
| // sendEvent sends rules to all subscribe watchers | ||||
| func (t *table) sendEvent(r *Event) { | ||||
| 	t.RLock() | ||||
| 	defer t.RUnlock() | ||||
|  | ||||
|   | ||||
| @@ -9,6 +9,40 @@ var ( | ||||
| 	ErrWatcherStopped = errors.New("routing table watcher stopped") | ||||
| ) | ||||
|  | ||||
| // EventType defines routing table event | ||||
| type EventType int | ||||
|  | ||||
| const ( | ||||
| 	// CreateEvent is emitted when new route has been created | ||||
| 	CreateEvent EventType = iota | ||||
| 	// DeleteEvent is emitted when an existing route has been deleted | ||||
| 	DeleteEvent | ||||
| 	// UpdateEvent is emitted when a routing table has been updated | ||||
| 	UpdateEvent | ||||
| ) | ||||
|  | ||||
| // String returns string representation of the event | ||||
| func (et EventType) String() string { | ||||
| 	switch et { | ||||
| 	case CreateEvent: | ||||
| 		return "CREATE" | ||||
| 	case DeleteEvent: | ||||
| 		return "DELETE" | ||||
| 	case UpdateEvent: | ||||
| 		return "UPDATE" | ||||
| 	default: | ||||
| 		return "UNKNOWN" | ||||
| 	} | ||||
| } | ||||
|  | ||||
| // Event is returned by a call to Next on the watcher. | ||||
| type Event struct { | ||||
| 	// Type defines type of event | ||||
| 	Type EventType | ||||
| 	// Route is table rout | ||||
| 	Route Route | ||||
| } | ||||
|  | ||||
| // WatchOption is used to define what routes to watch in the table | ||||
| type WatchOption func(*WatchOptions) | ||||
|  | ||||
| @@ -16,19 +50,11 @@ type WatchOption func(*WatchOptions) | ||||
| // Watcher returns updates to the routing table | ||||
| type Watcher interface { | ||||
| 	// Next is a blocking call that returns watch result | ||||
| 	Next() (*Result, error) | ||||
| 	Next() (*Event, error) | ||||
| 	// Stop stops watcher | ||||
| 	Stop() | ||||
| } | ||||
|  | ||||
| // Result is returned by a call to Next on the watcher. | ||||
| type Result struct { | ||||
| 	// Action is routing table action which is either of add, delete or update | ||||
| 	Action string | ||||
| 	// Route is table rout | ||||
| 	Route Route | ||||
| } | ||||
|  | ||||
| // WatchOptions are table watcher options | ||||
| type WatchOptions struct { | ||||
| 	// Specify destination address to watch | ||||
| @@ -54,14 +80,14 @@ func WatchNetwork(n string) WatchOption { | ||||
|  | ||||
| type tableWatcher struct { | ||||
| 	opts    WatchOptions | ||||
| 	resChan chan *Result | ||||
| 	resChan chan *Event | ||||
| 	done    chan struct{} | ||||
| } | ||||
|  | ||||
| // Next returns the next noticed action taken on table | ||||
| // TODO: this needs to be thought through properly | ||||
| // we are aiming to provide the same watch options Query() provides | ||||
| func (w *tableWatcher) Next() (*Result, error) { | ||||
| func (w *tableWatcher) Next() (*Event, error) { | ||||
| 	for { | ||||
| 		select { | ||||
| 		case res := <-w.resChan: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user