bugfix: The web interface now refreshes when the config file is changed! (#281)
This commit is contained in:
parent
86b2187236
commit
5a644b0856
|
|
@ -184,6 +184,8 @@ message GetReadyzResponse {
|
||||||
string status = 1;
|
string status = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
message EventConfigChanged {}
|
||||||
|
|
||||||
service OliveTinApiService {
|
service OliveTinApiService {
|
||||||
rpc GetDashboardComponents(GetDashboardComponentsRequest) returns (GetDashboardComponentsResponse) {
|
rpc GetDashboardComponents(GetDashboardComponentsRequest) returns (GetDashboardComponentsResponse) {
|
||||||
option (google.api.http) = {
|
option (google.api.http) = {
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,7 @@ func main() {
|
||||||
|
|
||||||
executor := executor.DefaultExecutor()
|
executor := executor.DefaultExecutor()
|
||||||
executor.AddListener(websocket.ExecutionListener)
|
executor.AddListener(websocket.ExecutionListener)
|
||||||
|
config.AddListener(websocket.OnConfigChanged)
|
||||||
|
|
||||||
go onstartup.Execute(cfg, executor)
|
go onstartup.Execute(cfg, executor)
|
||||||
go oncron.Schedule(cfg, executor)
|
go oncron.Schedule(cfg, executor)
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,14 @@ var (
|
||||||
Name: "olivetin_config_reloaded_count",
|
Name: "olivetin_config_reloaded_count",
|
||||||
Help: "The number of times the config has been reloaded",
|
Help: "The number of times the config has been reloaded",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
listeners []func()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func AddListener(l func()) {
|
||||||
|
listeners = append(listeners, l)
|
||||||
|
}
|
||||||
|
|
||||||
func Reload(cfg *Config) {
|
func Reload(cfg *Config) {
|
||||||
if err := viper.UnmarshalExact(&cfg); err != nil {
|
if err := viper.UnmarshalExact(&cfg); err != nil {
|
||||||
log.Errorf("Config unmarshal error %+v", err)
|
log.Errorf("Config unmarshal error %+v", err)
|
||||||
|
|
@ -34,4 +40,8 @@ func Reload(cfg *Config) {
|
||||||
|
|
||||||
cfg.SetDir(path.Dir(viper.ConfigFileUsed()))
|
cfg.SetDir(path.Dir(viper.ConfigFileUsed()))
|
||||||
cfg.Sanitize()
|
cfg.Sanitize()
|
||||||
|
|
||||||
|
for _, l := range listeners {
|
||||||
|
l()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ import (
|
||||||
ws "github.com/gorilla/websocket"
|
ws "github.com/gorilla/websocket"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
"google.golang.org/protobuf/encoding/protojson"
|
"google.golang.org/protobuf/encoding/protojson"
|
||||||
|
"google.golang.org/protobuf/reflect/protoreflect"
|
||||||
"net/http"
|
"net/http"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -24,6 +25,12 @@ var marshalOptions = protojson.MarshalOptions{
|
||||||
EmitUnpopulated: true,
|
EmitUnpopulated: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func OnConfigChanged() {
|
||||||
|
evt := &pb.EventConfigChanged{}
|
||||||
|
|
||||||
|
broadcast(evt)
|
||||||
|
}
|
||||||
|
|
||||||
var ExecutionListener WebsocketExecutionListener
|
var ExecutionListener WebsocketExecutionListener
|
||||||
|
|
||||||
type WebsocketExecutionListener struct{}
|
type WebsocketExecutionListener struct{}
|
||||||
|
|
@ -72,12 +79,19 @@ func (WebsocketExecutionListener) OnExecutionFinished(logEntry *executor.Interna
|
||||||
ExecutionFinished: logEntry.ExecutionFinished,
|
ExecutionFinished: logEntry.ExecutionFinished,
|
||||||
}
|
}
|
||||||
|
|
||||||
broadcast("ExecutionFinished", le)
|
broadcast(le)
|
||||||
}
|
}
|
||||||
|
|
||||||
func broadcast(messageType string, pbmsg *pb.LogEntry) {
|
func broadcast(pbmsg protoreflect.ProtoMessage) {
|
||||||
payload, err := marshalOptions.Marshal(pbmsg)
|
payload, err := marshalOptions.Marshal(pbmsg)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("websocket marshal error: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
messageType := pbmsg.ProtoReflect().Descriptor().FullName()
|
||||||
|
|
||||||
// <EVIL>
|
// <EVIL>
|
||||||
// So, the websocket wants to encode messages using the same protomarshaller
|
// So, the websocket wants to encode messages using the same protomarshaller
|
||||||
// as the REST API - this gives consistency instead of using encoding/json
|
// as the REST API - this gives consistency instead of using encoding/json
|
||||||
|
|
@ -97,13 +111,8 @@ func broadcast(messageType string, pbmsg *pb.LogEntry) {
|
||||||
hackyMessage = append(hackyMessage, []byte("}")...)
|
hackyMessage = append(hackyMessage, []byte("}")...)
|
||||||
// </EVIL>
|
// </EVIL>
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("websocket marshal error: %v", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, client := range clients {
|
for _, client := range clients {
|
||||||
client.conn.WriteMessage(1, hackyMessage)
|
client.conn.WriteMessage(ws.TextMessage, hackyMessage)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ function websocketOnMessage (msg) {
|
||||||
e.payload = j.payload
|
e.payload = j.payload
|
||||||
|
|
||||||
switch (j.type) {
|
switch (j.type) {
|
||||||
|
case 'EventConfigChanged':
|
||||||
case 'ExecutionFinished':
|
case 'ExecutionFinished':
|
||||||
window.dispatchEvent(e)
|
window.dispatchEvent(e)
|
||||||
break
|
break
|
||||||
|
|
|
||||||
|
|
@ -134,6 +134,8 @@ function main () {
|
||||||
initMarshaller()
|
initMarshaller()
|
||||||
setupLogSearchBox()
|
setupLogSearchBox()
|
||||||
|
|
||||||
|
window.addEventListener('EventConfigChanged', fetchGetDashboardComponents) // For websocket
|
||||||
|
|
||||||
window.fetch('webUiSettings.json').then(res => {
|
window.fetch('webUiSettings.json').then(res => {
|
||||||
return res.json()
|
return res.json()
|
||||||
}).then(res => {
|
}).then(res => {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue