github.com/blystad/deis@v0.11.0/logger/syslog/handler.go (about) 1 package syslog 2 3 // Handler handles syslog messages 4 type Handler interface { 5 // Handle should return Message (maybe modified) for future processing by 6 // other handlers or return nil. If Handle is called with nil message it 7 // should complete all remaining work and properly shutdown before return. 8 Handle(*Message) *Message 9 } 10 11 // BaseHandler is designed to simplify the creation of real handlers. It 12 // implements Handler interface using nonblocking queuing of messages and 13 // simple message filtering. 14 type BaseHandler struct { 15 queue chan *Message 16 end chan struct{} 17 filter func(*Message) bool 18 ft bool 19 } 20 21 // NewBaseHandler creates BaseHandler using a specified filter. If filter is nil 22 // or if it returns true messages are passed to BaseHandler internal queue 23 // (of qlen length). If filter returns false or ft is true messages are returned 24 // to server for future processing by other handlers. 25 func NewBaseHandler(qlen int, filter func(*Message) bool, ft bool) *BaseHandler { 26 return &BaseHandler{ 27 queue: make(chan *Message, qlen), 28 end: make(chan struct{}), 29 filter: filter, 30 ft: ft, 31 } 32 } 33 34 // Handle inserts m in an internal queue. It immediately returns even if 35 // queue is full. If m == nil it closes queue and waits for End method call 36 // before return. 37 func (h *BaseHandler) Handle(m *Message) *Message { 38 if m == nil { 39 close(h.queue) // signal that there is no more messages for processing 40 <-h.end // wait for handler shutdown 41 return nil 42 } 43 if h.filter != nil && !h.filter(m) { 44 // m doesn't match the filter 45 return m 46 } 47 // Try queue m 48 select { 49 case h.queue <- m: 50 default: 51 } 52 if h.ft { 53 return m 54 } 55 return nil 56 } 57 58 // Get returns first message from internal queue. It waits for message if queue 59 // is empty. It returns nil if there is no more messages to process and handler 60 // should shutdown. 61 func (h *BaseHandler) Get() *Message { 62 m, ok := <-h.queue 63 if ok { 64 return m 65 } 66 return nil 67 } 68 69 // Queue returns the BaseHandler internal queue as a read-only channel. You can use 70 // it directly, especially if your handler needs to select from multiple channels 71 // or have to work without blocking. You need to check if this channel is closed by 72 // sender and properly shutdown in this case. 73 func (h *BaseHandler) Queue() <-chan *Message { 74 return h.queue 75 } 76 77 // End signals the server that the handler properly shutdown. You need to call End 78 // only if Get has returned nil before. 79 func (h *BaseHandler) End() { 80 close(h.end) 81 }