func (r *Router) serve(serfClient *client.RPCClient) error { var ( eventCh chan client.EventRecord ) // register for member events, user events and queries eventCh = make(chan client.EventRecord) if _, err := serfClient.Stream("member-join,member-leave,member-failed,user,query", eventCh); err != nil { return fmt.Errorf("failed to initialize event stream. Error: %s", err) } for { select { case e, ok := <-eventCh: if !ok { return fmt.Errorf("event channel was unexpectedly closed") } log.Infof("Event received: %+v", e) if _, ok := e.(client.QueryEventRecord); ok { r.handleQuery(serfClient, e.(client.QueryEventRecord)) } else { r.handleEvent(e) } } } }
func (r *Router) handleQuery(serfClient *client.RPCClient, query client.QueryEventRecord) { r.Lock() defer r.Unlock() var ( response []byte handlerFunc ResponderFunc ok bool err error ) if f := r.findHandlerFunc(query.Name); f == nil { log.Infof("no handler for query: %q", query.Name) return } else if handlerFunc, ok = f.(ResponderFunc); !ok { log.Infof("no handler for query: %q", query.Name) return } if response, err = handlerFunc(query.Name, query); err != nil { log.Infof("query handler failed. Error: %s", err) // failure returned by handlers are not considered fatal // TODO: handle panics inside event handlers as well return } if err := serfClient.Respond(query.ID, response); err != nil { log.Errorf("responding to query failed. Response body: %v, Error: %s", response, err) } }