// receive reads result from the decoder in a loop and sends down the result channel. func (sw *StreamWatcher) receive() { defer close(sw.result) defer sw.Stop() defer util.HandleCrash() for { action, obj, err := sw.source.Decode() if err != nil { // Ignore expected error. if sw.stopping() { return } switch err { case io.EOF: // watch closed normally case io.ErrUnexpectedEOF: glog.V(1).Infof("Unexpected EOF during watch stream event decoding: %v", err) default: msg := "Unable to decode an event from the watch stream: %v" if util.IsProbableEOF(err) { glog.V(5).Infof(msg, err) } else { glog.Errorf(msg, err) } } return } sw.result <- Event{ Type: action, Object: obj, } } }
// Copy the reader to the response. The created WebSocket is closed after this // method completes. func (r *Reader) Copy(w http.ResponseWriter, req *http.Request) error { go func() { defer util.HandleCrash() websocket.Server{Handshake: r.handshake, Handler: r.handle}.ServeHTTP(w, req) }() return <-r.err }
// ignoreReceives reads from a WebSocket until it is closed, then returns. If timeout is set, the // read and write deadlines are pushed every time a new message is received. func ignoreReceives(ws *websocket.Conn, timeout time.Duration) { defer util.HandleCrash() var data []byte for { resetTimeout(ws, timeout) if err := websocket.Message.Receive(ws, &data); err != nil { return } } }
// Open the connection and create channels for reading and writing. func (conn *Conn) Open(w http.ResponseWriter, req *http.Request) ([]io.ReadWriteCloser, error) { go func() { defer util.HandleCrash() defer conn.Close() websocket.Server{Handshake: conn.handshake, Handler: conn.handle}.ServeHTTP(w, req) }() <-conn.ready rwc := make([]io.ReadWriteCloser, len(conn.channels)) for i := range conn.channels { rwc[i] = conn.channels[i] } return rwc, nil }