func StartSubscriber(ws *websocket.Conn) *giles.Subscriber { wss := &WebSocketSubscriber{ws: ws, outbound: make(chan []byte, clientQueueSize), closeC: make(chan bool), notify: make(chan bool)} wss.subscription = giles.NewSubscriber(wss.closeC, 10, wss.handleError) m.initialize <- wss go func(wss *WebSocketSubscriber) { ticker := time.NewTicker(pingPeriod) defer func() { ticker.Stop() m.remove <- wss }() for { select { case val := <-wss.subscription.C: wss.Lock() wss.ws.WriteJSON(val) wss.Unlock() case <-ticker.C: wss.Lock() if err := wss.ws.WriteMessage(websocket.PingMessage, []byte{}); err != nil { wss.Unlock() log.Errorf("web socket error %v", err) return } wss.Unlock() } } }(wss) return wss.subscription }
func StartHTTPSubscriber(rw http.ResponseWriter) *giles.Subscriber { var err error _closeC := rw.(http.CloseNotifier).CloseNotify() hs := &HTTPSubscriber{rw: rw, closed: false, _closeC: _closeC, closeC: make(chan bool)} hs.watchForClose() hs.subscription = giles.NewSubscriber(hs.closeC, 10, hs.handleError) writer := json.NewEncoder(rw) rw.Header().Set("Content-Type", "application/json; charset=utf-8") rw.Header().Set("Access-Control-Allow-Origin", "*") go func(hs *HTTPSubscriber, writer *json.Encoder) { log.Debugf(">>> NEW HTTP REPUB %v", hs) for val := range hs.subscription.C { hs.Lock() if hs.closed { hs.Unlock() break } log.Debugf("repub %v", val) err = writer.Encode(val) hs.Unlock() hs.handleError(err) hs.Lock() hs.rw.Write([]byte{'\n', '\n'}) if flusher, ok := hs.rw.(http.Flusher); ok && !hs.closed { flusher.Flush() } hs.Unlock() } }(hs, writer) return hs.subscription }
func StartTCPJSONSubscriber(conn net.Conn) *giles.Subscriber { tsub := &TCPJSONSubscriber{conn: conn, closed: false, closeC: make(chan bool)} tsub.subscription = giles.NewSubscriber(tsub.closeC, 10, tsub.handleError) writer := json.NewEncoder(tsub.conn) go func(tsub *TCPJSONSubscriber, writer *json.Encoder) { var err error for val := range tsub.subscription.C { tsub.Lock() if tsub.closed { tsub.conn.Close() tsub.closeC <- true tsub.Unlock() break } log.Debugf("repub %v", val) err = writer.Encode(val) tsub.Unlock() tsub.handleError(err) } }(tsub, writer) return tsub.subscription }
func (bwh *BOSSWaveHandler) StartSubscriber(vk string, query KeyValueQuery) *giles.Subscriber { bws := &BWSubscriber{ bw: bwh.bw, nonce: query.Nonce, closeC: make(chan bool), baseURI: fmt.Sprintf("%s,", vk[:len(vk)-1]), } bws.allURI = bws.baseURI + "all" bws.timeseriesURI = bws.baseURI + "timeseries" bws.metadataURI = bws.baseURI + "metadata" bws.diffURI = bws.baseURI + "diff" bws.subscription = giles.NewSubscriber(bws.closeC, 10, bws.handleError) go func(bws *BWSubscriber) { for val := range bws.subscription.C { var reply []bw.PayloadObject log.Debugf("subscription got val %+v", val) switch t := val.(type) { case common.SmapMessageList: log.Debugf("smap messages list %+v", t) pos := POsFromSmapMessageList(query.Nonce, t) reply = append(reply, pos...) case common.DistinctResult: log.Debugf("distinct list %+v", t) reply = append(reply, POFromDistinctResult(query.Nonce, t)) default: log.Debug("type %T", val) } if err := bwh.iface.PublishSignal(bws.allURI, reply...); err != nil { log.Error(errors.Wrap(err, "Could not publish reply")) } } }(bws) return bws.subscription }