Showing posts with label protobuf. Show all posts
Showing posts with label protobuf. Show all posts

Sunday, September 13, 2020

Random Thoughts, Some Progress

 Lots of work at work, so not as much time for projects.

Smattering of thoughts:  

  1. Godot doesn't really seem ready for prime-time with c# yet.  Not bad, and we will keep and eye on it.   I'll try to make my libraries in a way that theoretically we could make them agnostic to the engine (probably biggest issue there will be the way the engine does mesh representation), and hopefully as little code as possible on the engine side.
  2. Keeping a close eye on wasmer/wasmtime.   I think I will still need wasmer, since it is .netstandard 2.0.  The Wasmtime restriction to .netstandard 2.1 is a problem with unity (and probably godot).   Though I can run the emissaries as separate processes, I think I want to do that later.  Let's get it working before we go too crazy with a 'scale out' plan, just not preclude ourselves from going that way.  I have very little time to code, so have to make a bee-line to functionality.   We will probably revisit this when Unity changes their .net model, to .net core or possible .net 5 (the .net version to rule them all).  Both of these projects are ticking a long.   I still find wasmer's WAPM projects a powerful missing link, though version pinning and signed downloads of external code would have to happen.
  3. Starting to look at some naked-codeless emissaries, which just have content in them.  It's one option for the emissary, just to hold objects, or to hold references to objects.   I'm refactoring the ldraw code so I can just put lego entities in.  Later these can indirect to an URL rather than needing to be in the emissary--though they will have to match a full checksum when they download--they will then be able to be proxy signed.   Looking at getting an STL loader too.  Then some work on a universal (protobuf based) mesh format.
  4. Very intrigued by Kafka.   I think log based messages might be a giant win over Rabbit/AMQP style pub/sub.   The use-case is that the world server can simply make every client a producer and everyone can be a consumer to see their scenes change.   The interesting thing is that perhaps, if you don't have a complete cache of the scene, you can then traverse the log in the reverse direction back to a fixed low-water mark (which represents having every entity having presented it's status in the log at least once), fully recapitulating the status of the scene.  You have to traverse it backwards since a given entity might report many times, and you don't want to have the scene be remade in order.   Physics will have to be suspended during the repaint.  Also, if  you mark each status with the timestamp of the last previous change, you can make a hash to ignore all but the last status report of every entity (and not have to keep inactive entities in your hash -- if their last-changed is back before the low-water mark.   Also Kafka messages can be done in protobuf (a supported standard).    World server will still need a database to track everything.   Might be easier than the redis idea.  Have to experiment.  I need a skeleton world server.  I'm building a Kafka server to try out.
  5. These log based systems like Kafka (and really like the mongo oplog) are intriguing.  I'm thinking of a way to do the image and mesh caches that use this, where they use a given number of fixed length cache files (likely memory mapped), and the oldest one times out and causes the oldest cached entries to be reloaded into a real file.   This doesn't fix evacuating trivial files or keeping core-files which are constantly used. Trivial files of course will fall out when the logs get rotated.  It's a very powerful scheme for keeping high-integrity databases without needed to do wild random access during setup, or any need to do garbage collection.

Sunday, May 3, 2020

Emissary Architecture Starting to Take Shape

So, I've been pretty deep in WASM architecture, and the WASI APIs.   I've pretty much gotten to the point where we can launch an emissary and interact with it.    So, now, it's time to actually build out the 3DOM APIs for interacting with the emissary and the message passing loops.   Initially I'm going to start building a Rust Module for this.  I do want to do this with other languages as it becomes practical.   I'd love to be able to do C# and Python, but I don't think they're quite there yet.   I've used mono-wasm to generate c# wasm, and pyodide for Python, but so far they're not particularly oriented to WASI yet and are more intended to run on a website (and interact with a DOM).

I think it will mostly go like this: one exposed setup method from the API layer, which will receive a protobuf buffer.   This will be using 'proto 3' and will be decoded and processed.  This gives us a backward and forward compatible startup.    The startup will register callbacks on the rust side for the message pump to process.   Then the emissary's 'main' basically returns.    A channel is created via grpc to the browser and eventually to the entity/avatar server.  Protobuf packets are passed in via these callback mechanisms.   The emissary runs and then returns and possibly returns one or more protobuf packets.   For now, I don't intend the emissary to have a thread to run when it is not processing a callback.   Initially I'd rather an emissary not be able to do things like mining bitcoin or other such undesirable activity.   The service managing the emissary will probably have a call timeout and will disable it if it doesn't respond in a timely fashion.

This facility kind of makes it hard to directly do gRPC, but at least we can do gRPC-like behavior passing protobufs around.   I can cheat and have a grpc wrapper call which contains a command type and the protobuf  as a raw vector.   The server calls are tricker, as the interior emissary-to-server gRPC calls are theoretically private (and ad-hoc)--so their formats can't be known by this middleware layer which is operating the emissary for the browser.    There are some up-and-coming grpc proxies out there.   Or I will have to do my own, which is just calling methods on the emissary and returning an answer (no actual network involved).   With my WASI layer, I could actually permit the emissary to open a socket, but I don't trust this yet. 

So, now I actually have to work out exactly what the browser-emissary interaction (which I've been calling the 3DOM api) actually is and how it works.   I've got some prototypes of this that I worked out last summer, but now I have to start building my .proto files to implement it.

Initially there will be no world, and no entity server to work this out.  I'll have the concept of a "system entity", which can simply run inside the loading area (which will eventually will become a mini-world which is served from inside the browser).   Also, eventually we'll have an avatar server, but initially the avatar is mostly just a vr camera FPS rig, with no smarts.    I'll be doing some checkins soon of some of this structure. 

The emissary will have an initial built-in parasitic overhead to have to have a copy of the loading module and the protobuf module.  Eventually I'm sure I'll be able to dynamically link such things so they can be shared between emissaries.   There's an effort for a package manager for webassembly (like npm) called wapm.  Perhaps there can be a package manifest and emissaries can be dynamically loaded.   I am ultimately intending for there to be hundreds, if not tens of thousands of emissaries to exist (in the distant future).   So optimization, sharing, hot-deploy, and versioning will have to be seamless.


Random Thoughts, Some Progress

 Lots of work at work, so not as much time for projects. Smattering of thoughts:   Godot doesn't really seem ready for prime-time with c...