Commit 2e1f2609 by Torkel Ödegaard

feat(grafana_live): more work pushing data to websocket, #4355

parent 92f20b9b
......@@ -3,7 +3,11 @@ package dtos
import "encoding/json"
type StreamMessage struct {
Stream string `json:"stream"`
Metric string `json:"metric"`
Datapoints [][]json.Number `json:"Datapoints"`
Stream string `json:"stream"`
Series []StreamMessageSeries `json:"series"`
}
type StreamMessageSeries struct {
Name string `json:"name"`
Datapoints [][]json.Number `json:"datapoints"`
}
......@@ -81,7 +81,10 @@ func (c *connection) handleMessage(message []byte) {
switch msgType {
case "subscribe":
h.subChannel <- &streamSubscription{name: streamName, conn: c}
case "unsubscribe":
h.subChannel <- &streamSubscription{name: streamName, conn: c, remove: true}
}
}
func (c *connection) write(mt int, payload []byte) error {
......
......@@ -17,8 +17,9 @@ type hub struct {
}
type streamSubscription struct {
conn *connection
name string
conn *connection
name string
remove bool
}
var h = hub{
......@@ -40,15 +41,24 @@ func (h *hub) run() {
case c := <-h.register:
h.connections[c] = true
log.Info("Live: New connection (Total count: %v)", len(h.connections))
case c := <-h.unregister:
if _, ok := h.connections[c]; ok {
log.Info("Live: Closing Connection (Total count: %v)", len(h.connections))
delete(h.connections, c)
close(c.send)
}
// hand stream subscriptions
case sub := <-h.subChannel:
log.Info("Live: Connection subscribing to: %v", sub.name)
log.Info("Live: Subscribing to: %v, remove: %v", sub.name, sub.remove)
subscribers, exists := h.streams[sub.name]
// handle unsubscribe
if exists && sub.remove {
delete(subscribers, sub.conn)
continue
}
if !exists {
subscribers = make(map[*connection]bool)
h.streams[sub.name] = subscribers
......@@ -58,13 +68,19 @@ func (h *hub) run() {
// handle stream messages
case message := <-h.streamChannel:
subscribers, exists := h.streams[message.Stream]
if !exists {
if !exists || len(subscribers) == 0 {
log.Info("Live: Message to stream without subscribers: %v", message.Stream)
continue
}
messageBytes, _ := simplejson.NewFromAny(message).Encode()
for sub := range subscribers {
// check if channel is open
if _, ok := h.connections[sub]; !ok {
delete(subscribers, sub)
continue
}
select {
case sub.send <- messageBytes:
default:
......
......@@ -42,7 +42,7 @@ export class LiveSrv {
};
this.conn.onmessage = (evt) => {
console.log("Live: message received:", evt.data);
this.handleMessage(evt.data);
};
this.conn.onerror = (evt) => {
......@@ -61,6 +61,23 @@ export class LiveSrv {
return this.initPromise;
}
handleMessage(message) {
message = JSON.parse(message);
if (!message.stream) {
console.log("Error: stream message without stream!", message);
return;
}
var observer = this.observers[message.stream];
if (!observer) {
this.removeObserver(message.stream, null);
return;
}
observer.next(message);
}
reconnect() {
// no need to reconnect if no one cares
if (_.keys(this.observers).length === 0) {
......@@ -89,6 +106,7 @@ export class LiveSrv {
}
removeObserver(stream, observer) {
console.log('unsubscribe', stream);
delete this.observers[stream];
this.getConnection().then(conn => {
......
......@@ -2,11 +2,13 @@
import {liveSrv} from 'app/core/core';
import {Observable} from 'vendor/npm/rxjs/Observable';
export class GrafanaStreamDS {
subscription: any;
/** @ngInject */
constructor(private $q) {
constructor() {
}
......@@ -16,11 +18,23 @@ export class GrafanaStreamDS {
}
var target = options.targets[0];
if (this.subscription) {
if (this.subscription.stream !== target.stream) {
this.subscription.unsubscribe();
} else {
return Promise.resolve({data: []});
}
}
var observable = liveSrv.subscribe(target.stream);
this.subscription = observable.subscribe(data => {
console.log("grafana stream ds data!", data);
});
this.subscription.stream = target.stream;
return Promise.resolve({data: []});
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment