Skip to content

Commit

Permalink
wip: hotreload (iter 2)
Browse files Browse the repository at this point in the history
Signed-off-by: gfanton <8671905+gfanton@users.noreply.github.com>
  • Loading branch information
gfanton committed Dec 18, 2023
1 parent 3f60d39 commit 6393b3d
Show file tree
Hide file tree
Showing 9 changed files with 276 additions and 54 deletions.
40 changes: 22 additions & 18 deletions contribs/gnodev/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
gnodev "github.com/gnolang/gno/contribs/gnodev/pkg/dev"
"github.com/gnolang/gno/contribs/gnodev/pkg/events"
"github.com/gnolang/gno/contribs/gnodev/pkg/rawterm"
"github.com/gnolang/gno/contribs/gnodev/pkg/watcher"
"github.com/gnolang/gno/gno.land/pkg/gnoweb"
"github.com/gnolang/gno/gnovm/pkg/gnoenv"
"github.com/gnolang/gno/gnovm/pkg/gnomod"
Expand Down Expand Up @@ -127,6 +128,8 @@ func execDev(cfg *devCfg, args []string, io commands.IO) error {
cancel(nil)
})

emitter := events.NewEmitter()

// Setup Dev Node
// XXX: find a good way to export or display node logs
devNode, err := setupDevNode(ctx, rt, pkgpaths, gnoroot)
Expand All @@ -140,13 +143,13 @@ func execDev(cfg *devCfg, args []string, io commands.IO) error {
rt.Taskf(NodeLogName, "Chain ID: %s\n", devNode.Config().ChainID())

// Setup packages watcher
pathChangeCh := make(chan []string, 1)
go func() {
defer close(pathChangeCh)
// pathChangeCh := make(chan []string, 1)
// go func() {
// defer close(pathChangeCh)

err := runPkgsWatcher(ctx, cfg, devNode.ListPkgs(), pathChangeCh)
cancel(err)
}()
// err := runPkgsWatcher(ctx, cfg, devNode.ListPkgs(), pathChangeCh)
// cancel(err)
// }()

// Create server
mux := http.NewServeMux()
Expand Down Expand Up @@ -177,6 +180,12 @@ func execDev(cfg *devCfg, args []string, io commands.IO) error {

rt.Taskf(WebLogName, "Listener: http://%s\n", server.Addr)

watcher, err := watcher.NewPackageWatcher(loggerHotReload, eventsSrv)
if err != nil {
return fmt.Errorf("unable to setup packages watcher")
}
defer watcher.Stop()

// GnoDev should be ready, run event loop
rt.Taskf("[Ready]", "for commands and help, press `h`")

Expand All @@ -198,13 +207,11 @@ Gno Dev Helper:
func runEventLoop(ctx context.Context,
cfg *devCfg,
rt *rawterm.RawTerm,
eventsSrv *events.Server,
dnode *dev.Node,
pathsCh <-chan []string,
watch *watcher.PackageWatcher,
) error {
nodeOut := rt.NamespacedWriter(NodeLogName)
keyOut := rt.NamespacedWriter(KeyPressLogName)
hotOut := rt.NamespacedWriter(HotReloadLogName)

keyPressCh := listenForKeyPress(keyOut, rt)
for {
Expand All @@ -213,28 +220,25 @@ func runEventLoop(ctx context.Context,
select {
case <-ctx.Done():
return context.Cause(ctx)
case paths, ok := <-pathsCh:
case err, ok := <-watch.PackagesUpdate:
if !ok {
return nil
}

if cfg.verbose {
for _, path := range paths {
fmt.Fprintf(hotOut, "path %q has been modified\n", path)
}
return fmt.Errorf("watch errors: %w", err)
case pkgs, ok := <-watch.PackagesUpdate:
if !ok {
return nil
}

fmt.Fprintln(nodeOut, "Loading package updates...")
if err = dnode.UpdatePackages(paths...); err != nil {
if err = dnode.UpdatePackages(pkgs.PackagesPath()...); err != nil {
return fmt.Errorf("unable to update packages: %w", err)
}

fmt.Fprintln(nodeOut, "Reloading...")
err = dnode.Reload(ctx)

// send update files events
eventsSrv.SendJSONEvent(events.NewFilesUpdateEvent(paths))

checkForError(rt, err)

case key, ok := <-keyPressCh:
Expand Down
26 changes: 26 additions & 0 deletions contribs/gnodev/pkg/dev/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package dev

import "github.com/gnolang/gno/contribs/gnodev/pkg/events"

const (
EvtReload events.EventType = "NODE_RELOAD"
EvtReset events.EventType = "NODE_RESET"
)

type EventReloadData struct{}

func newReloadEvent() *events.Event {
return &events.Event{
Type: EvtReload,
Data: &EventReloadData{},
}
}

type EventResetdData struct{}

func newResetEvent() *events.Event {
return &events.Event{
Type: EvtReload,
Data: &EventResetdData{},
}
}
28 changes: 20 additions & 8 deletions contribs/gnodev/pkg/dev/node.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"fmt"

"github.com/gnolang/gno/contribs/gnodev/pkg/events"
"github.com/gnolang/gno/gno.land/pkg/gnoland"
"github.com/gnolang/gno/gno.land/pkg/integration"
vmm "github.com/gnolang/gno/gno.land/pkg/sdk/vm"
Expand Down Expand Up @@ -33,8 +34,9 @@ const gnoDevChainID = "tendermint_test" // XXX: this is hardcoded and cannot be
type Node struct {
*node.Node

logger log.Logger
pkgs PkgsMap // path -> pkg
evtEmitter events.Emitter
logger log.Logger
pkgs PkgsMap // path -> pkg
}

var (
Expand All @@ -48,7 +50,7 @@ var (
}
)

func NewDevNode(ctx context.Context, logger log.Logger, pkgslist []string) (*Node, error) {
func NewDevNode(ctx context.Context, evtEmitter events.Emitter, logger log.Logger, pkgslist []string) (*Node, error) {
mpkgs, err := newPkgsMap(pkgslist)
if err != nil {
return nil, fmt.Errorf("unable map pkgs list: %w", err)
Expand Down Expand Up @@ -82,9 +84,10 @@ func NewDevNode(ctx context.Context, logger log.Logger, pkgslist []string) (*Nod
}

return &Node{
Node: node,
pkgs: mpkgs,
logger: logger,
evtEmitter: evtEmitter,
Node: node,
pkgs: mpkgs,
logger: logger,
}, nil
}

Expand Down Expand Up @@ -142,7 +145,12 @@ func (d *Node) Reset(ctx context.Context) error {
Txs: txs,
}

return d.reset(ctx, genesis)
if err := d.reset(ctx, genesis); err != nil {
return fmt.Errorf("unable to reset the node: %w", err)
}

d.evtEmitter.Emit(newResetEvent())
return nil
}

func (d *Node) ReloadAll(ctx context.Context) error {
Expand All @@ -160,7 +168,6 @@ func (d *Node) ReloadAll(ctx context.Context) error {
}

func (d *Node) Reload(ctx context.Context) error {

// save current state
state, err := d.saveState(ctx)
if err != nil {
Expand Down Expand Up @@ -201,6 +208,11 @@ func (d *Node) Reload(ctx context.Context) error {
}
}

if err != nil {
return fmt.Errorf("unable to reload the node: %w", err)
}

d.evtEmitter.Emit(newReloadEvent())
return nil
}

Expand Down
17 changes: 0 additions & 17 deletions contribs/gnodev/pkg/events/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,7 @@ package events

type EventType string

const (
FileUpdate EventType = "FILE_UPDATE"
)

type Event struct {
Type EventType `json:"type"`
Data interface{} `json:"data"`
}

type FileUpdateData struct {
Files []string `json:"files"`
}

func NewFilesUpdateEvent(files []string) *Event {
return &Event{
Type: FileUpdate,
Data: &FileUpdateData{
Files: files,
},
}
}
7 changes: 0 additions & 7 deletions contribs/gnodev/pkg/events/reload_test.go

This file was deleted.

9 changes: 6 additions & 3 deletions contribs/gnodev/pkg/events/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ import (
"github.com/gorilla/websocket"
)

type Emitter interface {
Emit(evt *Event)
}

type Server struct {
logger log.Logger
upgrader websocket.Upgrader
Expand All @@ -21,7 +25,7 @@ func NewServer(logger log.Logger) *Server {
clients: make(map[*websocket.Conn]struct{}),
upgrader: websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true // Adjust the origin policy as needed
return true // XXX: adjust this
},
},
}
Expand Down Expand Up @@ -51,7 +55,7 @@ func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) {
}
}

func (s *Server) SendJSONEvent(evt *Event) {
func (s *Server) Emit(evt *Event) {
if len(s.clients) == 0 {
return
}
Expand All @@ -61,7 +65,6 @@ func (s *Server) SendJSONEvent(evt *Event) {

s.logger.Info("sending json", "clients", len(s.clients), "event", evt.Type, "data", evt.Data)
for conn := range s.clients {

err := conn.WriteJSON(evt)
if err != nil {
s.logger.Error("write json", "error", err)
Expand Down
1 change: 0 additions & 1 deletion contribs/gnodev/pkg/events/static/hotreload.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@

(function() {
var ws = new WebSocket('ws://{{- .Remote -}}');

Expand Down
37 changes: 37 additions & 0 deletions contribs/gnodev/pkg/watcher/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package watcher

import (
events "github.com/gnolang/gno/contribs/gnodev/pkg/events"
)

const (
EvtPackagesUpdate events.EventType = "PACKAGES_UPDATE"
)

type PackageUpdate struct {
Package string `json:"package"`
Files []string `json:"files"`
}

type PackagesUpdate []PackageUpdate

func (pkgsu PackagesUpdate) PackagesPath() []string {
pkgs := make([]string, len(pkgsu))
for i, pkg := range pkgsu {
pkgs[i] = pkg.Package
}
return pkgs
}

type EventPackagesUpdateData struct {
Pkgs []PackageUpdate `json:"packages"`
}

func newPackagesUpdateEvent(pkgs []PackageUpdate) *events.Event {
return &events.Event{
Type: EvtPackagesUpdate,
Data: &EventPackagesUpdateData{
Pkgs: pkgs,
},
}
}
Loading

0 comments on commit 6393b3d

Please sign in to comment.