Skip to content

Instantly share code, notes, and snippets.

@kumavis
Last active May 4, 2025 10:36
Show Gist options
  • Save kumavis/c8461202ae3817662a740693cbd0d98c to your computer and use it in GitHub Desktop.
Save kumavis/c8461202ae3817662a740693cbd0d98c to your computer and use it in GitHub Desktop.
OCapN concepts

OCapN

🚧 Work in progress.

An implementation of the OCapN protocol.

Includes codecs for Syrup encoded messages.

Concepts

Types of Things

There are four kinds of things that can be received and sent:

  • Copy Data, sent as frozen data
  • Local Objects, sent as Presences, received as the original local values
  • Remote Objects, sent and received as Presences
  • Promises (Remote and Local), sent and received as Promises

Objects are functions, or bags of named functions. To compliment the Promises there are also Resolvers, which are just a type of Object, that allow you to control a Promise's fate.

Your first Object

You've established a connection to another peer. Now what? To bootstrap interactivity, you're given access to an intial remote object: The Bootstrap Object. This usually has some useful methods on them for interacting with the remote system. Those methods will often return other objects, and you can call methods on them as well.

Calling a remote method

When calling a method on a remote object, you might want to get a response. The system creates a Promise and Resolver pair locally to represent you "asking a question and expecting an answer". The system sends the Resolver reference along with your question, and the remote peer will send a message to your Resolver with the outcome, resolving (or rejecting) the Promise.

Eventual Send and Promise Pipelining

It may so happen that, rather than wait for the response to be sent to you, you'd like to immediately submit an additional method call to the result of the first. To allow for this, the system specified an "answerPosition" on your first question, and the remote peer stored a Promise for the result, addressable by that answerPosition. You can now immediately send a method invocation to that answerPosition, and it will be invoked when the Promise at that answerPosition is resolved. This feature of allowing you to call methods on Promises before they are resolved is called "Eventual Send".

Since we get to specify the answerPosition, we know where to direct the subsequent call before we even hear back from the remote peer. Its trivial to set up a long chain of method invocations on yet unresolved Promises, each calling the result of the last, and they can all be sent immediately. This feature of avoiding unnecesary roundtrips is called "Promise Pipelining".

Import/Export tables

In order to keep track of all the Objects and Promises, the system maintains an Import/Export table per peer. The table tracks:

  • the identifier to use when referring to an object when communicating
  • which objects are imported from the remote peer
  • which objects have been exported by us
  • the Resolvers corresponding to imported Remote Promises
  • the Local Promises indexed by the the peer-specified answerPosition
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment