dotcloud/docker

View on GitHub
libnetwork/networkdb/watch.go

Summary

Maintainability
A
0 mins
Test Coverage
package networkdb

import (
    "net"

    "github.com/docker/go-events"
)

type opType uint8

const (
    opCreate opType = 1 + iota
    opUpdate
    opDelete
)

type event struct {
    Table     string
    NetworkID string
    Key       string
    Value     []byte
}

// NodeTable represents table event for node join and leave
const NodeTable = "NodeTable"

// NodeAddr represents the value carried for node event in NodeTable
type NodeAddr struct {
    Addr net.IP
}

// CreateEvent generates a table entry create event to the watchers
type CreateEvent event

// UpdateEvent generates a table entry update event to the watchers
type UpdateEvent event

// DeleteEvent generates a table entry delete event to the watchers
type DeleteEvent event

// Watch creates a watcher with filters for a particular table or
// network or any combination of the tuple. If any of the
// filter is an empty string it acts as a wildcard for that
// field. Watch returns a channel of events, where the events will be
// sent.
func (nDB *NetworkDB) Watch(tname, nid string) (*events.Channel, func()) {
    var matcher events.Matcher

    if tname != "" || nid != "" {
        matcher = events.MatcherFunc(func(ev events.Event) bool {
            var evt event
            switch ev := ev.(type) {
            case CreateEvent:
                evt = event(ev)
            case UpdateEvent:
                evt = event(ev)
            case DeleteEvent:
                evt = event(ev)
            }

            if tname != "" && evt.Table != tname {
                return false
            }

            if nid != "" && evt.NetworkID != nid {
                return false
            }

            return true
        })
    }

    ch := events.NewChannel(0)
    sink := events.Sink(events.NewQueue(ch))

    if matcher != nil {
        sink = events.NewFilter(sink, matcher)
    }

    nDB.broadcaster.Add(sink)
    return ch, func() {
        nDB.broadcaster.Remove(sink)
        ch.Close()
        sink.Close()
    }
}

func makeEvent(op opType, tname, nid, key string, value []byte) events.Event {
    ev := event{
        Table:     tname,
        NetworkID: nid,
        Key:       key,
        Value:     value,
    }

    switch op {
    case opCreate:
        return CreateEvent(ev)
    case opUpdate:
        return UpdateEvent(ev)
    case opDelete:
        return DeleteEvent(ev)
    }

    return nil
}