Example #1
0
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
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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
}