livebud / bud

The Full-Stack Web Framework for Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add Windows Support

matthewmueller opened this issue · comments

Windows support is currently blocked by:

Bud's compiler will also transition to using Go plugins, which also do not have Windows support yet:

I haven't tested it yet, but you should be able to use Bud with the Windows Subsystem for Linux (WSL).

If you get this working, please let us know how!

Reading through golang/go#19282 it seems that Windows support for Go plugins is currently not in development and there are no development plans in the nearer future.

Also the general sentiment in that issue thread seems to be that Go plugin support is flaky and half-baked even on platforms where it is supported (see also golang/go#20461 and golang/go#27751), so it might be better not to depend on the built-in Go plugin system.

I was able to get it working on WSL. From a fresh install of Ubuntu WSL I just needed to install go and npm and I was up and running.

From a browser on Windows just go to http://localhost:3000 instead of http://0.0.0.0:3000.

I will also mention that I ran into | rename /tmp/bud-create-4082930893 hello: invalid cross-device link when attempting to run bud create hello under the default /mnt/c/... within WSL, changing to directory under $HOME resolved the issue.

I am also running into an issue with the hot reloading where whenever I save a change I get:

| Ready on http://0.0.0.0:3000
| signal: interrupt

and it hangs any further calls, although I'm still digging into why.

@FeldrinH Since plugin builds will stay local and don't need to be closed, the mentioned constraints are acceptable for bud's purposes. Go plugins will be used to allow you to bring your own code generators, transformers and commands.

For windows, build tags plus something like https://github.com/hashicorp/go-plugin will suffice. It'll just be slower to boot for window's users.

@theeyed Could you send an ABRT signal to the bud process when it's hanging and share the stack trace? https://pro-tips-dot-com.tumblr.com/post/47677612115/kill-a-hung-go-process-and-print-stack-traces. That may help us narrow down the problem. The cross-link issue is also discussed in #30 and there's also a discussion about hanging WSL2 process happening in #38.

kill -ABRT <pid>
SIGABRT: abort
PC=0x4674c3 m=2 sigcode=0

goroutine 0 [idle]:
runtime.futex()
        /usr/local/go/src/runtime/sys_linux_amd64.s:553 +0x23
runtime.futexsleep(0x5d6314d97a3?, 0x70400?, 0x7faea7630dc0?)
        /usr/local/go/src/runtime/os_linux.go:72 +0xaf
runtime.notetsleep_internal(0xfe2ad8, 0xdf8475800)
        /usr/local/go/src/runtime/lock_futex.go:201 +0xc5
runtime.notetsleep(0x5d6314d95ea?, 0x7fae00000002?)
        /usr/local/go/src/runtime/lock_futex.go:224 +0x34
runtime.sysmon()
        /usr/local/go/src/runtime/proc.go:5102 +0x1c9
runtime.mstart1()
        /usr/local/go/src/runtime/proc.go:1418 +0x93
runtime.mstart0()
        /usr/local/go/src/runtime/proc.go:1376 +0x79
runtime.mstart()
        /usr/local/go/src/runtime/asm_amd64.s:367 +0x5

goroutine 1 [semacquire, 2 minutes]:
sync.runtime_Semacquire(0xc0000021a0?)
        /usr/local/go/src/runtime/sema.go:56 +0x25
sync.(*WaitGroup).Wait(0xc000291601?)
        /usr/local/go/src/sync/waitgroup.go:136 +0x52
golang.org/x/sync/errgroup.(*Group).Wait(0xc0002916c0)
        /home/aherring/go/pkg/mod/golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:40 +0x27
github.com/livebud/bud/runtime/command/run.(*Command).Run(0xc0002891c0, {0xc9e468?, 0xc000291600?})
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/runtime/command/run/run.go:37 +0x22f
github.com/livebud/bud/package/commander.(*Command).parse(0xc00028c980, {0xc9e468, 0xc000291600}, {0xc00013c010, 0x0, 0x0})
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/package/commander/commander.go:186 +0x442
github.com/livebud/bud/package/commander.(*Command).parse(0xc00028c900, {0xc9e468, 0xc000291600}, {0xc00013c010, 0x1, 0x1})
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/package/commander/commander.go:154 +0x338
github.com/livebud/bud/package/commander.(*CLI).Parse(0xc0001a5e98, {0xc9e4a0?, 0xc000122000?}, {0xc00013c010, 0x1, 0x1})
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/package/commander/commander.go:90 +0xbf
github.com/theeyed/bud_hello/bud/.cli/command.(*CLI).Parse(0xc0002891a0, {0xc9e4a0, 0xc000122000}, {0xc00013c010, 0x1, 0x1})
        /home/aherring/source/bud/hello/bud/.cli/command/command.go:58 +0xb9c
github.com/theeyed/bud_hello/bud/.cli/program.(*Program).Run(...)
        /home/aherring/source/bud/hello/bud/.cli/program/program.go:73
github.com/theeyed/bud_hello/bud/.cli/program.run({0xc9e4a0, 0xc000122000}, {0xc00013c010, 0x1, 0x1})
        /home/aherring/source/bud/hello/bud/.cli/program/program.go:47 +0x68
github.com/theeyed/bud_hello/bud/.cli/program.Run({0xc9e4a0?, 0xc000122000?}, {0xc00013c010?, 0x9f7880?, 0xc0000021a0?})
        /home/aherring/source/bud/hello/bud/.cli/program/program.go:28 +0x2c
main.main()
        /home/aherring/source/bud/hello/bud/.cli/main.go:11 +0x65

goroutine 10 [chan receive, 2 minutes]:
github.com/livebud/bud/runtime/web.shutdown.func1()
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/runtime/web/serve.go:40 +0x50
created by github.com/livebud/bud/runtime/web.shutdown
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/runtime/web/serve.go:39 +0xb8

goroutine 35 [select, 2 minutes]:
os/exec.(*Cmd).Start.func2()
        /usr/local/go/src/os/exec/exec.go:449 +0x75
created by os/exec.(*Cmd).Start
        /usr/local/go/src/os/exec/exec.go:448 +0x6fc

goroutine 36 [chan receive, 2 minutes]:
github.com/livebud/bud/internal/sig.Trap.func1()
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/internal/sig/trap.go:14 +0x2d
created by github.com/livebud/bud/internal/sig.Trap
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/internal/sig/trap.go:13 +0xaf

goroutine 38 [syscall, 2 minutes]:
os/signal.signal_recv()
        /usr/local/go/src/runtime/sigqueue.go:151 +0x2f
os/signal.loop()
        /usr/local/go/src/os/signal/signal_unix.go:23 +0x19
created by os/signal.Notify.func1.1
        /usr/local/go/src/os/signal/signal.go:151 +0x2a

goroutine 39 [IO wait, 2 minutes]:
internal/poll.runtime_pollWait(0x7faea5df9758, 0x72)
        /usr/local/go/src/runtime/netpoll.go:302 +0x89
internal/poll.(*pollDesc).wait(0xc0000b2780?, 0x0?, 0x0)
        /usr/local/go/src/internal/poll/fd_poll_runtime.go:83 +0x32
internal/poll.(*pollDesc).waitRead(...)
        /usr/local/go/src/internal/poll/fd_poll_runtime.go:88
internal/poll.(*FD).Accept(0xc0000b2780)
        /usr/local/go/src/internal/poll/fd_unix.go:614 +0x22c
net.(*netFD).accept(0xc0000b2780)
        /usr/local/go/src/net/fd_unix.go:172 +0x35
net.(*TCPListener).accept(0xc00000e390)
        /usr/local/go/src/net/tcpsock_posix.go:139 +0x28
net.(*TCPListener).Accept(0xc00000e390)
        /usr/local/go/src/net/tcpsock.go:288 +0x3d
net/http.(*Server).Serve(0xc0000fc000, {0xc9dd78, 0xc00000e390})
        /usr/local/go/src/net/http/server.go:3039 +0x385
github.com/livebud/bud/runtime/web.serve({0xc9e468, 0xc000291680}, {0xc00002a9f0, 0xa}, {0xc99520?, 0xc000285080}, {0xc9dd78, 0xc00000e390})
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/runtime/web/serve.go:24 +0xfb
github.com/livebud/bud/runtime/web.Serve({0xc9e468, 0xc000291680}, {0xc9dd78, 0xc00000e390}, {0xc99520, 0xc000285080})
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/runtime/web/serve.go:14 +0x6d
github.com/livebud/bud/package/hot.(*Server).ListenAndServe(0x0?, {0xc9e468, 0xc000291680}, {0xab6a24?, 0x0?})
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/package/hot/server.go:33 +0x76
github.com/livebud/bud/runtime/command/run.(*Command).startHot(...)
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/runtime/command/run/run.go:116
github.com/livebud/bud/runtime/command/run.(*Command).Run.func1()
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/runtime/command/run/run.go:33 +0x31
golang.org/x/sync/errgroup.(*Group).Go.func1()
        /home/aherring/go/pkg/mod/golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:57 +0x67
created by golang.org/x/sync/errgroup.(*Group).Go
        /home/aherring/go/pkg/mod/golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:54 +0x8d

goroutine 40 [semacquire, 2 minutes]:
sync.runtime_Semacquire(0xc0002c4ea0?)
        /usr/local/go/src/runtime/sema.go:56 +0x25
sync.(*WaitGroup).Wait(0xc00056c301?)
        /usr/local/go/src/sync/waitgroup.go:136 +0x52
golang.org/x/sync/errgroup.(*Group).Wait(0xc00056c3c0)
        /home/aherring/go/pkg/mod/golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:40 +0x27
github.com/livebud/bud/package/watcher.Watch({0xc9e468, 0xc000291680}, {0xab533d, 0x1}, 0xc00056c080)
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/package/watcher/watcher.go:174 +0x4cf
github.com/livebud/bud/runtime/command/run.(*Command).startApp(0xc0002891c0, {0xc9e468?, 0xc000291680}, 0xc000285080)
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/runtime/command/run/run.go:76 +0x3a7
github.com/livebud/bud/runtime/command/run.(*Command).Run.func2()
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/runtime/command/run/run.go:36 +0x29
golang.org/x/sync/errgroup.(*Group).Go.func1()
        /home/aherring/go/pkg/mod/golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:57 +0x67
created by golang.org/x/sync/errgroup.(*Group).Go
        /home/aherring/go/pkg/mod/golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:54 +0x8d

goroutine 1303 [syscall]:
syscall.Syscall6(0xe8, 0xc, 0xc0008afc14, 0x7, 0xffffffffffffffff, 0x0, 0x0)
        /usr/local/go/src/syscall/asm_linux_amd64.s:43 +0x5
golang.org/x/sys/unix.EpollWait(0x2?, {0xc0008afc14?, 0x2?, 0xc000380880?}, 0xc0008afcdc?)
        /home/aherring/go/pkg/mod/golang.org/x/sys@v0.0.0-20220408201424-a24fb2fb8a0f/unix/zsyscall_linux_amd64.go:56 +0x58
github.com/fsnotify/fsnotify.(*fdPoller).wait(0xc00030c1c0)
        /home/aherring/go/pkg/mod/github.com/fsnotify/fsnotify@v1.5.1/inotify_poller.go:87 +0x7d
github.com/fsnotify/fsnotify.(*Watcher).readEvents(0xc00029c050)
        /home/aherring/go/pkg/mod/github.com/fsnotify/fsnotify@v1.5.1/inotify.go:193 +0x26e
created by github.com/fsnotify/fsnotify.NewWatcher
        /home/aherring/go/pkg/mod/github.com/fsnotify/fsnotify@v1.5.1/inotify.go:60 +0x1c5

goroutine 1304 [select]:
github.com/livebud/bud/package/watcher.Watch.func8()
        /home/aherring/go/pkg/mod/github.com/livebud/bud@v0.1.0/package/watcher/watcher.go:138 +0x10e
golang.org/x/sync/errgroup.(*Group).Go.func1()
        /home/aherring/go/pkg/mod/golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:57 +0x67
created by golang.org/x/sync/errgroup.(*Group).Go
        /home/aherring/go/pkg/mod/golang.org/x/sync@v0.0.0-20210220032951-036812b2e83c/errgroup/errgroup.go:54 +0x8d

rax    0xfffffffffffffffc
rbx    0x0
rcx    0x4674c3
rdx    0x0
rdi    0xfe2ad8
rsi    0x80
rbp    0x7faea7630d70
rsp    0x7faea7630d28
r8     0x0
r9     0x0
r10    0x7faea7630d60
r11    0x246
r12    0x7faea7630d60
r13    0x7ffd13ed9e3f
r14    0xc0000029c0
r15    0x7faea7630fc0
rip    0x4674c3
rflags 0x246
cs     0x33
fs     0x0
gs     0x0

Thanks Alex! I think I know the problem and it's related to the 0.0.0.0 issue you mentioned earlier. I have 0.0.0.0 hardcoded in a few places, specifically in the hot reload client.

I'm changing the default to 127.0.0.1. PR up here: #41

So I think the hanging issue should be solved in v0.1.1. Could you try again?

To upgrade, run:

curl -sf curl https://raw.githubusercontent.com/livebud/bud/main/install.sh | sh

After retrying on the latest version, with the basic example, I am still seeing the hanging on changes. The error is logged from process.Close() at:

if err := process.Close(); err != nil {
console.Error(err.Error())
return nil
}

I was able to get around it by either removing the return nil to allow it to proceed or by adding a check to ignore signal: interrupt similar to isExitStatus and isWaitError in the exe command:

if sp != nil {
if err := sp.Signal(os.Interrupt); err != nil {
sp.Kill()
}
}
if err := cmd.Wait(); err != nil {
if !isExitStatus(err) && !isWaitError(err) {
return err
}
}

Thanks for narrowing this down Alex! I just added a PR to hopefully address this. Since you're running Bud locally, do you mind pulling down the branch to confirm? Otherwise, no worries, I'll release a new version after CI passes.

That did the trick. Last thing I'm looking through for WSL is it is currently failing to connect to the hotserver.

Oh, interesting. So you're seeing errors on the client-side saying unable to connect to http://127.0.0.1:35729?

Added some details to #48

Since this issue has kind of meandered, I'll close it in favor of: #81