2015-04-03 20:58:56 +00:00
|
|
|
package events
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
"time"
|
|
|
|
|
2015-09-10 22:01:18 +00:00
|
|
|
"github.com/docker/docker/context"
|
|
|
|
|
2015-04-03 20:58:56 +00:00
|
|
|
"github.com/docker/docker/pkg/jsonmessage"
|
|
|
|
"github.com/docker/docker/pkg/pubsub"
|
|
|
|
)
|
|
|
|
|
|
|
|
const eventsLimit = 64
|
|
|
|
|
|
|
|
// Events is pubsub channel for *jsonmessage.JSONMessage
|
|
|
|
type Events struct {
|
|
|
|
mu sync.Mutex
|
|
|
|
events []*jsonmessage.JSONMessage
|
|
|
|
pub *pubsub.Publisher
|
|
|
|
}
|
|
|
|
|
|
|
|
// New returns new *Events instance
|
|
|
|
func New() *Events {
|
|
|
|
return &Events{
|
|
|
|
events: make([]*jsonmessage.JSONMessage, 0, eventsLimit),
|
|
|
|
pub: pubsub.NewPublisher(100*time.Millisecond, 1024),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Subscribe adds new listener to events, returns slice of 64 stored last events
|
|
|
|
// channel in which you can expect new events in form of interface{}, so you
|
|
|
|
// need type assertion.
|
|
|
|
func (e *Events) Subscribe() ([]*jsonmessage.JSONMessage, chan interface{}) {
|
|
|
|
e.mu.Lock()
|
|
|
|
current := make([]*jsonmessage.JSONMessage, len(e.events))
|
|
|
|
copy(current, e.events)
|
|
|
|
l := e.pub.Subscribe()
|
|
|
|
e.mu.Unlock()
|
|
|
|
return current, l
|
|
|
|
}
|
|
|
|
|
|
|
|
// Evict evicts listener from pubsub
|
|
|
|
func (e *Events) Evict(l chan interface{}) {
|
|
|
|
e.pub.Evict(l)
|
|
|
|
}
|
|
|
|
|
|
|
|
// Log broadcasts event to listeners. Each listener has 100 millisecond for
|
|
|
|
// receiving event or it will be skipped.
|
2015-09-10 22:01:18 +00:00
|
|
|
func (e *Events) Log(ctx context.Context, action, id, from string) {
|
2015-09-15 19:33:11 +00:00
|
|
|
now := time.Now().UTC()
|
2015-09-10 22:01:18 +00:00
|
|
|
jm := &jsonmessage.JSONMessage{RequestID: ctx.RequestID(), Status: action, ID: id, From: from, Time: now.Unix(), TimeNano: now.UnixNano()}
|
2015-09-15 18:28:22 +00:00
|
|
|
e.mu.Lock()
|
|
|
|
if len(e.events) == cap(e.events) {
|
|
|
|
// discard oldest event
|
|
|
|
copy(e.events, e.events[1:])
|
|
|
|
e.events[len(e.events)-1] = jm
|
|
|
|
} else {
|
|
|
|
e.events = append(e.events, jm)
|
|
|
|
}
|
|
|
|
e.mu.Unlock()
|
|
|
|
e.pub.Publish(jm)
|
2015-04-03 20:58:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// SubscribersCount returns number of event listeners
|
|
|
|
func (e *Events) SubscribersCount() int {
|
|
|
|
return e.pub.Len()
|
|
|
|
}
|