Move proxy/router
This commit is contained in:
120
router/watcher.go
Normal file
120
router/watcher.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package router
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// EventType defines routing table event
|
||||
type EventType int
|
||||
|
||||
const (
|
||||
// Create is emitted when a new route has been created
|
||||
Create EventType = iota
|
||||
// Delete is emitted when an existing route has been deleted
|
||||
Delete
|
||||
// Update is emitted when an existing route has been updated
|
||||
Update
|
||||
)
|
||||
|
||||
// String returns human readable event type
|
||||
func (t EventType) String() string {
|
||||
switch t {
|
||||
case Create:
|
||||
return "create"
|
||||
case Delete:
|
||||
return "delete"
|
||||
case Update:
|
||||
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
|
||||
// Timestamp is event timestamp
|
||||
Timestamp time.Time
|
||||
// Route is table route
|
||||
Route Route
|
||||
}
|
||||
|
||||
// WatchOption is used to define what routes to watch in the table
|
||||
type WatchOption func(*WatchOptions)
|
||||
|
||||
// Watcher defines routing table watcher interface
|
||||
// Watcher returns updates to the routing table
|
||||
type Watcher interface {
|
||||
// Next is a blocking call that returns watch result
|
||||
Next() (*Event, error)
|
||||
// Chan returns event channel
|
||||
Chan() (<-chan *Event, error)
|
||||
// Stop stops watcher
|
||||
Stop()
|
||||
}
|
||||
|
||||
// WatchOptions are table watcher options
|
||||
type WatchOptions struct {
|
||||
// Service allows to watch specific service routes
|
||||
Service string
|
||||
}
|
||||
|
||||
// WatchService sets what service routes to watch
|
||||
// Service is the microservice name
|
||||
func WatchService(s string) WatchOption {
|
||||
return func(o *WatchOptions) {
|
||||
o.Service = s
|
||||
}
|
||||
}
|
||||
|
||||
type tableWatcher struct {
|
||||
sync.RWMutex
|
||||
id string
|
||||
opts WatchOptions
|
||||
resChan chan *Event
|
||||
done chan struct{}
|
||||
}
|
||||
|
||||
// Next returns the next noticed action taken on table
|
||||
// TODO: right now we only allow to watch particular service
|
||||
func (w *tableWatcher) Next() (*Event, error) {
|
||||
for {
|
||||
select {
|
||||
case res := <-w.resChan:
|
||||
switch w.opts.Service {
|
||||
case res.Route.Service, "*":
|
||||
return res, nil
|
||||
default:
|
||||
continue
|
||||
}
|
||||
case <-w.done:
|
||||
return nil, ErrWatcherStopped
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Chan returns watcher events channel
|
||||
func (w *tableWatcher) Chan() (<-chan *Event, error) {
|
||||
return w.resChan, nil
|
||||
}
|
||||
|
||||
// Stop stops routing table watcher
|
||||
func (w *tableWatcher) Stop() {
|
||||
w.Lock()
|
||||
defer w.Unlock()
|
||||
|
||||
select {
|
||||
case <-w.done:
|
||||
return
|
||||
default:
|
||||
close(w.done)
|
||||
}
|
||||
}
|
||||
|
||||
var (
|
||||
// ErrWatcherStopped is returned when routing table watcher has been stopped
|
||||
ErrWatcherStopped = errors.New("watcher stopped")
|
||||
)
|
||||
Reference in New Issue
Block a user