-
Notifications
You must be signed in to change notification settings - Fork 194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can SwingSet run on browser? #58
Comments
Hi @danfinlay ! We have not been. But we've been trying to stick to the discipline that, as much as possible, we assume only a standard modern JavaScript language, while keeping all host dependencies small and contained. So guessing: It probably doesn't quite work, but can be made to work without too much effort. The the "it" there is running an entire SwingSet (the kernel and all the vats using that kernel) in one JavaScript process. When you say "cross-process", what do you have in mind? |
There was probably a better word I could have chosen. In this context by "process" I mean independent JavaScript event loops that do not have access to each other's memory or objects. I guess this is sometimes called "across an async membrane"? Still learning some of the lingo. Some examples of "separate processes":
I dream that things like the third use case (the ability to edit a specific paragraph in a document) could be as easy as Am I understanding correctly what role Swingset plays, and what it could do if it were modified to run within a browser? |
I think so, but cc'ing @warner, @michaelfig, and @kriskowal who can correct me where I misstep. Some of your scenarios would be supported by multiple vats within one swingset, and some by multiple swingsets talking to each other. When explaining vats and swingsets, I start with
Multiple vats within the same swingset effectively share one event loop, which is some interleaving of the turns for each of the member vats. Each turn of any vat runs to completion before anything happens in any other vat. There is no genuine parallelism within a swingset. An object within one vat can have a direct reference only to other objects in its own vat. For all other objects, it holds only a remote reference to them, in the form of a handled promise which communicate to their swingset kernel through a data only interface. Although we are actually running them all within one realm, we could switch these to separate realms without any observable difference. A separate worker within the browser is, to us, as separate as a remote server. Likewise with a background process, or anything reached over websockets or webrtc. We would put a separate swingset in each, each with its own comms vat. Whatever the low level communications mechanism is between these units, we'd need to abstract it into a vattp connection. Q-Connection did something similar. |
This helps a lot, thanks for clarifying the role between a vat and a SwingSet. Q-Connection is very nice, and maybe usable for what I was looking for at the moment. In part I was considering whether some of this prior work had tooling that I could use as an alternative to building capnode (a remote object-proxy library), and while its interface isn't as open-ended, I really like that it supports pipelining out of the box. I was also curious whether those messages were being cryptographically signed within SwingSet, or maybe you could point me to which layer of the stack the cryptographic serialization is happening at? |
There are a number of things I would do the same and differently with
Q-Connection if I were to pick it up and carry it again.
Notably, I’d get back in touch with Mark and Dean and figure out how to
hoist it atop the new standard promise. I’m not entirely sure that’s
possible without subverting it or further spec work for something like a
AsyncProxy(handler) that regular promises will forward messages to. I
understand they’ve given more thought to this.
I would also use WeakRef, finally, to collect entries in the connection’s
tables when nothing else refers to them. As written, all remote references
are tracked indefinitely or with an arbitrary map implementation. The
arbitrary map can be a fixed size cache, but the developer ergonomics for
that are pretty awful. They place an arbitrary limit on how many
outstanding remote references you can have and require you to code
defensively, with retry loops that recreate the chain of references to all
involved remote objects from the remote root API. Far better to retain the
Connection for the scope of a transaction and discard it all.
I would move the responsibility of JSON.stringify,parse to the stream
adapter and use bidirectional async iterables as the stream abstraction. I
would remove entirely the concern of adapting all the bonkers stream
abstractions to async iterables, leaving that to another library or other
libraries.
Q-Connection memoizes every individual local data object and transmits
nested objects shallowly, in postfix construction order. I would keep this.
This makes it possible to orchestrate the development of remote object
graphs, including those with cycles.
I would do something to accommodate binary payloads, and probably would use
a binary wire protocol instead of JSON. My first uses for Q-Connection
involved proxying an attenuated filesystem and it didn’t turn out to be
particularly useful because it couldn’t transit binary data.
In general, Q-Connection is really outrageously small. All the real work
happens in Q because Q exposes a promise constructor that’s like a Proxy
constructor. I would copy it and fiddle, not depend upon it. Most of the
work is in clawing that property back from the JavaScript Promise.
…On Thu, Sep 19, 2019 at 2:26 PM Dan Finlay ***@***.***> wrote:
This helps a lot, thanks for clarifying the role between a vat and a
SwingSet.
Q-Connection is very nice, and maybe usable for what I was looking for at
the moment. In part I was considering whether some of this prior work had
tooling that I could use as an alternative to building capnode
<https://www.npmjs.com/package/capnode> (a remote object-proxy library),
and while its interface isn't *as* open-ended, I really like that it
supports pipelining out of the box.
I was also curious whether those messages were being cryptographically
signed within SwingSet, or maybe you could point me to which layer of the
stack the cryptographic serialization is happening at?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<https://github.com/Agoric/SwingSet/issues/153?email_source=notifications&email_token=AAAOXBXGFB7MTIDQYVG6A73QKPU65A5CNFSM4IXEYTDKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOD7E36FQ#issuecomment-533315350>,
or mute the thread
<https://github.com/notifications/unsubscribe-auth/AAAOXBRKAUHHWKF673WXC2DQKPU65ANCNFSM4IXEYTDA>
.
|
The crypto should be happening within the vattp layer. The comms vat should not know about crypto. |
FWIW, I think of SwingSet as a library first, which must be embedded/instantiated inside some "host". The host creates the kernel and the initial vats, and gets back a controller. The host can use the controller to process the run-queue. The host should also (generally) set up some "devices" at the same time (e.g. the Mailbox device) and use them to cause messages to be added to the run queue. The host also provides something to store kernel+vat state in. The Our "cosmic-swingset" repo is a blockchain-based host for a swingset environment. Since the state management of the vats (checkpointing at the end of each large turn) is very similar to the state management of a blockchain (one checkpoint per block), it's fairly straightforward to treat the swingset library as the state machine inside the blockchain world: each signed transaction may deliver a message through the Mailbox device, and then for each block we process the runqueue to completion. We may have some work to do before it's possible, but in general you should be able to instantiate a swingset environment in a browser. But we have to decide what the "host" looks like, and how it satisfies the swingset's needs from the host: somewhere to store state (unless you're satisfied with ephemeral vats), some way to get messages in (unless you're satisfied with very short-lived vats), and some way for messages to get out (unless you're satisfied with having no side-effects). The work that may need to be done includes:
|
Three stores had been combined in Agoric#43.
Rewrite our state-management approach: pass in a state object when building the kernel/controller, and all kernel state will be read-from/written-to it as messages are processed. You can make that object persistent any way you like, as long as you pass an equivalent one into the kernel the next time the process starts. closes Agoric#58
…Agoric#58) * A test case for presence corruption with the eventual send candidate. * turn off test.only * Move this directory to the new location for SwingsetTests * Rename the root test case and add a comment explaining its purpose. fix the test after directory move.
@ski I think you asked me this question a few weeks ago. |
Hi @michaelfig I think this is closest to things you are working on, so may I assign you? |
The short answer of "can SwingSet run in a browser" is "not without a lot of work." The long answer is #58 (comment) And also, that work is not really on Agoric's roadmap at this time. A better question is "can a vat run in a browser" (i.e. without the deterministic persistent multi-vat world that SwingSet provides for)? The answer to that is "yes"! Use SES and CapTP, and be prepared to reestablish your remote objects from scratch on reload. You can take advantage of any platform features in this model (like async databases, remote hosts, etc): no need to be deterministic. What we're missing is LavaMoat integration to partition risk nearly as seamlessly as SwingSet provides. Our most obvious example of this is the wallet UI which uses SES and CapTP messaging to talk to the local ag-solo. It's in Svelte. We're making more examples of this kind of UI Really Soon Now. As far as making this pattern generalisable to other runtime environments: -cough-Endo-cough-. But as @danfinlay Closing this issue until somebody signs up to do the "lot of work" it would take. |
It seems like a bunch of the hard work has actually been done. I wonder how much is left:
The Compartment API is pretty mature by now.
#3171 seems to make that feasible.
I guess that part has a ways to go... but we're making progress: #1670 , see also #3180 |
The docs make this look like a command line tool, but is there a way to also run these vats and support cross-process communication within a browser?
The text was updated successfully, but these errors were encountered: