github.com/portworx/docker@v1.12.1/api/client/system/events_utils.go (about)

     1  package system
     2  
     3  import (
     4  	"encoding/json"
     5  	"io"
     6  	"sync"
     7  
     8  	"github.com/Sirupsen/logrus"
     9  	eventtypes "github.com/docker/engine-api/types/events"
    10  )
    11  
    12  // EventHandler is abstract interface for user to customize
    13  // own handle functions of each type of events
    14  type EventHandler interface {
    15  	Handle(action string, h func(eventtypes.Message))
    16  	Watch(c <-chan eventtypes.Message)
    17  }
    18  
    19  // InitEventHandler initializes and returns an EventHandler
    20  func InitEventHandler() EventHandler {
    21  	return &eventHandler{handlers: make(map[string]func(eventtypes.Message))}
    22  }
    23  
    24  type eventHandler struct {
    25  	handlers map[string]func(eventtypes.Message)
    26  	mu       sync.Mutex
    27  }
    28  
    29  func (w *eventHandler) Handle(action string, h func(eventtypes.Message)) {
    30  	w.mu.Lock()
    31  	w.handlers[action] = h
    32  	w.mu.Unlock()
    33  }
    34  
    35  // Watch ranges over the passed in event chan and processes the events based on the
    36  // handlers created for a given action.
    37  // To stop watching, close the event chan.
    38  func (w *eventHandler) Watch(c <-chan eventtypes.Message) {
    39  	for e := range c {
    40  		w.mu.Lock()
    41  		h, exists := w.handlers[e.Action]
    42  		w.mu.Unlock()
    43  		if !exists {
    44  			continue
    45  		}
    46  		logrus.Debugf("event handler: received event: %v", e)
    47  		go h(e)
    48  	}
    49  }
    50  
    51  // DecodeEvents decodes event from input stream
    52  func DecodeEvents(input io.Reader, ep eventProcessor) error {
    53  	dec := json.NewDecoder(input)
    54  	for {
    55  		var event eventtypes.Message
    56  		err := dec.Decode(&event)
    57  		if err != nil && err == io.EOF {
    58  			break
    59  		}
    60  
    61  		if procErr := ep(event, err); procErr != nil {
    62  			return procErr
    63  		}
    64  	}
    65  	return nil
    66  }