Skip to content

Commit

Permalink
Added synchronization of GUIs via websockets.
Browse files Browse the repository at this point in the history
  • Loading branch information
tvrzna committed Dec 21, 2023
1 parent 5db25b2 commit 0092023
Show file tree
Hide file tree
Showing 8 changed files with 116 additions and 3 deletions.
8 changes: 8 additions & 0 deletions context.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Context struct {
conf *Config
jobs []*Job
webServer *http.Server
wsService *WsService
}

// Init new context
Expand Down Expand Up @@ -113,6 +114,7 @@ func (c *Context) start(b *Job) {

cmd.Start()
go c.watchForInterrupt(b, cmd)
c.broadcastUpdate(b)

if err := cmd.Wait(); err != nil {
if exiterr, ok := err.(*exec.ExitError); ok {
Expand All @@ -136,6 +138,7 @@ func (c *Context) start(b *Job) {
log.Print("-- could not compress", b.WorkspacePath())
}
os.RemoveAll(b.WorkspacePath())
c.broadcastUpdate(b)

log.Printf("<< finished job #%s for %s", b.name, b.p.name)
}
Expand Down Expand Up @@ -183,6 +186,7 @@ func (c *Context) watchForInterrupt(b *Job, cmd *exec.Cmd) {
if status {
b.SetStatus(Stopped)
cmd.Process.Signal(os.Kill)
c.broadcastUpdate(b)
}
}

Expand Down Expand Up @@ -317,3 +321,7 @@ func (c *Context) compressFolder(outputPath, inputPath string) error {
}
return nil
}

func (c *Context) broadcastUpdate(b *Job) {
c.wsService.Broadcast(fmt.Sprintf("{\"update\": \"%s\"}", b.p.name))
}
1 change: 1 addition & 0 deletions context_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ func TestContext(t *testing.T) {
conf := LoadConfig([]string{"-t", tmpdir})

c := NewContext(conf)
NewWebSocketService(c)

p1 := c.OpenProject("project-1")
if err = os.MkdirAll(p1.dir, 0755); err != nil {
Expand Down
2 changes: 2 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
module github.com/tvrzna/lurch

go 1.20

require golang.org/x/net v0.19.0
2 changes: 2 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
3 changes: 3 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import (
"os"
"os/signal"
"syscall"

"golang.org/x/net/websocket"
)

func main() {
Expand All @@ -23,6 +25,7 @@ func main() {
func runWebServer(c *Context) {
mux := http.NewServeMux()

mux.Handle("/ws/", websocket.Handler(NewWebSocketService(c).HandleWebSocket))
mux.HandleFunc("/rest/", (&RestService{c: c}).HandleFunc)
mux.HandleFunc("/", NewWebService(c).HandleFunc)
c.webServer = &http.Server{Handler: mux, Addr: c.conf.getServerUri()}
Expand Down
1 change: 1 addition & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ make clean build
- [X] Hide dot project (e.g. `.ignored-project`) (0.3.0)
- [X] Dark theme (0.3.0)
- [X] Custom name of application (0.3.0)
- [X] Synchronization of UI via WebSockets
- [ ] Periodical watcher (running custom script saving state of last check)
- [ ] Pipelining (jobs started according the result status)
- [X] Starting build from build script
Expand Down
74 changes: 74 additions & 0 deletions websocket.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package main

import (
"sync"

"golang.org/x/net/websocket"
)

type WsService struct {
c *Context
mutex *sync.Mutex
cons []*WsConnection
}

type WsConnection struct {
id string
con *websocket.Conn
msg chan string
}

func NewWebSocketService(c *Context) *WsService {
w := &WsService{c: c, mutex: &sync.Mutex{}}
c.wsService = w
return w
}

func (w *WsService) HandleWebSocket(con *websocket.Conn) {
wsCon := &WsConnection{con: con, msg: make(chan string), id: randomToken(8)}

w.mutex.Lock()
w.cons = append(w.cons, wsCon)
w.mutex.Unlock()

defer con.Close()

for {
msg := <-wsCon.msg
if err := websocket.Message.Send(con, msg); err != nil {
w.removeFromSlice(wsCon)
break
}
}
}

func (w *WsService) Broadcast(msg string) {
for _, wsCon := range w.cons {
wsCon.msg <- msg
}
}

func (w *WsService) removeFromSlice(wsCon *WsConnection) {
w.mutex.Lock()
if index := w.indexOf(wsCon); index >= 0 {
if len(w.cons) == 1 {
w.cons = w.cons[:0]
} else {
w.cons = append(w.cons[:index], w.cons[index+1])
}
}
w.mutex.Unlock()
}

func (w *WsService) indexOf(wsCon *WsConnection) int {
for i, con := range w.cons {
if wsCon.Equals(con) {
return i
}
}
return -1
}

func (w *WsConnection) Equals(other *WsConnection) bool {
return w.id == other.id
}
28 changes: 25 additions & 3 deletions www/static/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ function initApp(name) {
}, 3000);
};

context.loadHistory = () => {
context.loadHistory = (suppressOpen) => {
context.addLoading();
$.get(appUrl + "/projects/" + context.projectName, {
success: data => {
Expand All @@ -52,7 +52,7 @@ function initApp(name) {
}
context.status = context.history[0].status;
context.showJob(undefined, context.history[0].name);
if (context.status == "inprogress") {
if (context.status == "inprogress" && !suppressOpen) {
context.setOutputCollapsed(false);
}
}
Expand Down Expand Up @@ -421,15 +421,35 @@ function initApp(name) {
app.attribute('ajsf-href', (el, value) => {
$(el).attr('href', value);
});

return app;
}

const appMap = new Map();

$('[ajsf]').each((i, el) => {
var appName = $(el).attr('ajsf');
if (appName != "lurch-settings") {
initApp(appName);
appMap.set(appName, initApp(appName));
}
});

function connectToWs() {
wsUrl = 'ws://' + window.location.host + window.location.pathname + 'ws/';
const socket = new WebSocket(wsUrl);
socket.addEventListener("message", (event) => {
let msg = JSON.parse(event.data);
let updateApp = msg["update"];
if (updateApp !== undefined) {
let app = appMap.get(updateApp);
app.context.loadHistory(true);
}
});
socket.addEventListener("close", () => {
setTimeout(connectToWs, 1000);
});
}

ajsf("lurch-settings", context => {
const themeItemName = "lurch.theme";

Expand All @@ -448,4 +468,6 @@ ajsf("lurch-settings", context => {
};

context.setTheme(localStorage.getItem(themeItemName));

connectToWs();
});

0 comments on commit 0092023

Please sign in to comment.