Use websocket to transmit logs

This commit is contained in:
nemunaire 2021-05-02 17:59:55 +02:00
commit d2a49e5740
6 changed files with 67 additions and 19 deletions

33
app.go
View file

@ -9,6 +9,7 @@ import (
"github.com/docker/docker/pkg/stdcopy"
"github.com/gin-gonic/gin"
"nhooyr.io/websocket"
"github.com/nemunaire/minifaas/engine/docker"
"github.com/nemunaire/minifaas/ui"
@ -41,7 +42,7 @@ func NewApp() App {
})
router.GET("/api/run", func(c *gin.Context) {
ctrid, err := docker.Run("hello-world")
ctrid, err := docker.Run("alpine", []string{"sh", "-c", "for i in `seq 20`; do echo $i; sleep 0.5; done"})
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err})
}
@ -49,15 +50,39 @@ func NewApp() App {
})
router.GET("/api/jobs/:jobid/logs", func(c *gin.Context) {
ws, err := websocket.Accept(c.Writer, c.Request, nil)
if err != nil {
log.Fatal("error get connection", err)
}
defer ws.Close(websocket.StatusInternalError, "the sky is falling")
stream, err := docker.Logs(c.Param("jobid"))
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err})
log.Fatal("Unable to get log stream:", err)
}
_, err = stdcopy.StdCopy(c.Writer, c.Writer, stream)
r, w := io.Pipe()
ctx, cancel := context.WithTimeout(c.Request.Context(), time.Second*10)
defer cancel()
go func(reader io.Reader) {
buf := make([]byte, 128)
for {
n, err := reader.Read(buf)
if err != nil {
break
}
ws.Write(ctx, websocket.MessageText, buf[:n])
}
}(r)
_, err = stdcopy.StdCopy(w, w, stream)
if err != nil && err != io.EOF {
c.JSON(http.StatusInternalServerError, gin.H{"error": err})
log.Fatal("Something goes wrong during stream:", err)
}
ws.Close(websocket.StatusNormalClosure, "")
})
app := App{