Closed mholt closed 1 year ago
Should this be moved to the actual discussion
area?
Either way. I can never tell when to use issues or discussions. Typically in my own projects I use issues for development items.
GitHub for project management is.....fun....
@mholt - Been reviewing this. Thanks for the awesome suggestions. I'd love to use Caddy as the http server but I guess changing the architecture of it is far too hardcore 😱 Some of what's been suggested here has already been done in slightly different forms so none of the above is unfeasible. The CLI generation might be a stretch but having a generic CLI that loads up a config to build up the CLI options would be realistic. Thanks again! 👍
Is your feature request related to a problem? Please describe.
I know there has been some talk about a server/hybrid mode (#1652 for example), and brainstorms about using Caddy as the server to benefit from its plugin ecosystem. After reviewing my (excellent) experience with Wails, I think I have some concrete suggestions/requests for Wails v3 related to how we expose functions/methods to the outside.
Currently, Wails exposes pure-Go functionality to the frontend (JS) through method bindings which it generates at compile-time. (In v3 this still applies, although I believe it is done with static analysis rather than runtime hacks.)
This is great but has some limitations/difficulties:
On that first point: I have an increasing need to be able to use the app in ways other than through the native webview frontend:
src/nv_gbm.c:99: GBM-DRV error (nv_gbm_bo_create): DRM_IOCTL_NVIDIA_GEM_ALLOC_NVKMS_MEMORY failed (ret=-1)
and the app is unusable / window is blank -- someone else actually reported this exact same error just hours after I first encountered it, after I reinstalled my OS and chose Arch for the first time; I suspect it has to do with the latest NVIDIA driver and its interop with either Wayland, the 6.2 kernel, or webkit2gtk, but either way, the app is unusable in its current state even though it's not Wails' fault.Describe the solution you'd like
I'd like to propose -- and discuss -- the possibility of approaching method bindings in a new way for v3:
Methods that are bound should accept a context as the first parameter (maybe optionally, but methods without it can't be canceled).
Implement cancellation: expose context creation and cancellation to the frontend. I envision an endpoint on the Wails runtime that returns an object from which bound methods can be called, like
const ctx = runtime.NewContext();
-- and then you can callctx.Foo(...)
to invoke bound methods. Ifctx.cancel()
is called, then the context passed to all the outstanding method calls on the Go side is canceled and the context state that is stored server-side can be cleaned up. Maybe actx.reset()
method can be used to cancel the context and replace it with a new one to make SPA page transitions easy without leaking memory. (Sure, we could just have a singleton pattern for the context, but allowing multiple contexts can be useful when a page has multiple things going on.)Continue to perform static analysis at compile-time to generate functions that can be called by JS frontends. :+1: However, these should be cancelable (see previous point). I'm not sure how the IPC works, but I imagine it involves a socket connection that can be closed, for example?
Generate thin HTTP routes over the bound methods. For example, a method defined as
Foo(ctx context.Context, a string, b int)
could have an HTTP route ofPOST /foo
where the payload is["a", 15]
for example. In other words, the payload is a JSON array where each element is a method argument. (Maybe methods with a single argument can elide the[ ]
for convenience.) These are naturally cancelable as net/http implements context cancellation. We'd probably want to implement some basic access controls like Host and Origin header enforcement (CORS, and to mitigate DNS rebinding attacks) to prevent rogue web pages running on the user's computer being able to access the server. This generation can be done automatically with reflection when the application initializes.Generate a thin CLI for bound methods. I've done this before with a Go program that registered HTTP routes, it was really nifty: basically the CLI derives the name of the subcommand from the path of the registered HTTP route (for example,
/api/new-account
had a command line subcommand ofnew-account
) and then the arguments formed the payload, for example a JSON struct would look like:myapp new-account --email you@example.com --password foobar
-- then some clever Go code generates the equivalent JSON payload and HTTP request, and sends it off to the currently-running, potentially-headless process.With 3 ways to access the API instead of just 1, it will be possible to:
Describe alternatives you've considered
One last thought, regarding using Caddy as the HTTP server: I agree this is a cool idea, as it would allow the HTTP endpoint to be greatly extended so that Wails apps could become much more versatile in both production and end-user environments.
The way it usually works with Caddy is you'd embed your app into Caddy (not the other way around). This is because Caddy does all the configuration management for you, etc. So when you run the program, you actually run Caddy, which then runs apps. You can extend Caddy's CLI to add subcommands, and rename the main command from Caddy to something else if needed, but the basic core of Caddy would remain. I don't know if that's desirable, but that's usually how things work.
There is one possible alternative that I have not explored in depth yet, and that is using the
caddyhttp
package independently of using the entire Caddy core and CLI. You'd probably have to still use functions from thecaddy/v2
package to load HTTP modules and such, but I don't know how much work would be needed to flip around the architecture so that you can truly embed Caddy into your app (instead embedding your app into Caddy). Anyone with a little time want to explore this?Additional context
Thanks for Wails, it continues to be great. I hope some of these suggestions can make it in. I'm willing to help iron out technical details.