add API list, and speculative sections on serialization and dilation
This commit is contained in:
parent
b4fdcfe53b
commit
20ec911b6c
93
docs/api.md
93
docs/api.md
|
@ -343,6 +343,32 @@ In Deferred mode, this just means waiting for the Deferred returned by
|
||||||
doesn't return anything) and waiting for the delegate's `wormhole_closed()`
|
doesn't return anything) and waiting for the delegate's `wormhole_closed()`
|
||||||
method to be called.
|
method to be called.
|
||||||
|
|
||||||
|
## Serialization
|
||||||
|
|
||||||
|
(this section is speculative: this code has not yet been written)
|
||||||
|
|
||||||
|
Wormhole objects can be serialized. This can be useful for apps which save
|
||||||
|
their own state before shutdown, and restore it when they next start up
|
||||||
|
again.
|
||||||
|
|
||||||
|
|
||||||
|
The `w.serialize()` method returns a dictionary which can be JSON encoded
|
||||||
|
into a unicode string (most applications will probably want to UTF-8 -encode
|
||||||
|
this into a bytestring before saving on disk somewhere).
|
||||||
|
|
||||||
|
To restore a Wormhole, call `wormhole.from_serialized(data, reactor,
|
||||||
|
delegate)`. This will return a wormhole in roughly the same state as was
|
||||||
|
serialized (of course all the network connections will be disconnected).
|
||||||
|
|
||||||
|
Serialization only works for delegated-mode wormholes (since Deferreds point
|
||||||
|
at functions, which cannot be serialized easily). It also only works for
|
||||||
|
"non-dilated" wormholes (see below).
|
||||||
|
|
||||||
|
To ensure correct behavior, serialization should probably only be done in
|
||||||
|
"journaled mode". See journal.md for details.
|
||||||
|
|
||||||
|
If you use serialization, be careful to never use the same partial wormhole
|
||||||
|
object twice.
|
||||||
|
|
||||||
## Bytes, Strings, Unicode, and Python 3
|
## Bytes, Strings, Unicode, and Python 3
|
||||||
|
|
||||||
|
@ -362,3 +388,70 @@ in python3):
|
||||||
* transit connection hints (e.g. "host:port")
|
* transit connection hints (e.g. "host:port")
|
||||||
* application identifier
|
* application identifier
|
||||||
* derived-key "purpose" string: `w.derive_key(PURPOSE, LENGTH)`
|
* derived-key "purpose" string: `w.derive_key(PURPOSE, LENGTH)`
|
||||||
|
|
||||||
|
## Full API list
|
||||||
|
|
||||||
|
action | Deferred-Mode | Delegated-Mode
|
||||||
|
-------------------------- | --------------------- | ----------------------------
|
||||||
|
w.generate_code(length=2) | |
|
||||||
|
w.set_code(code) | |
|
||||||
|
h=w.type_code() | |
|
||||||
|
| d=w.when_code() | dg.wormhole_got_code(code)
|
||||||
|
| d=w.when_verifier() | dg.wormhole_got_verifier(verf)
|
||||||
|
| d=w.when_version() | dg.wormhole_got_version(version)
|
||||||
|
w.send(data) | |
|
||||||
|
| d=w.when_received() | dg.wormhole_received(data)
|
||||||
|
key=w.derive_key(purpose, length) | |
|
||||||
|
w.close() | | dg.wormhole_closed(result)
|
||||||
|
| d=w.close() |
|
||||||
|
|
||||||
|
|
||||||
|
## Dilation
|
||||||
|
|
||||||
|
(this section is speculative: this code has not yet been written)
|
||||||
|
|
||||||
|
In the longer term, the Wormhole object will incorporate the "Transit"
|
||||||
|
functionality (see transit.md) directly, removing the need to instantiate a
|
||||||
|
second object. A Wormhole can be "dilated" into a form that is suitable for
|
||||||
|
bulk data transfer.
|
||||||
|
|
||||||
|
All wormholes start out "undilated". In this state, all messages are queued
|
||||||
|
on the Rendezvous Server for the lifetime of the wormhole, and server-imposed
|
||||||
|
number/size/rate limits apply. Calling `w.dilate()` initiates the dilation
|
||||||
|
process, and success is signalled via either `d=w.when_dilated()` firing, or
|
||||||
|
`dg.wormhole_dilated()` being called. Once dilated, the Wormhole can be used
|
||||||
|
as an IConsumer/IProducer, and messages will be sent on a direct connection
|
||||||
|
(if possible) or through the transit relay (if not).
|
||||||
|
|
||||||
|
What's good about a non-dilated wormhole?:
|
||||||
|
|
||||||
|
* setup is faster: no delay while it tries to make a direct connection
|
||||||
|
* survives temporary network outages, since messages are queued
|
||||||
|
* works with "journaled mode", allowing progress to be made even when both
|
||||||
|
sides are never online at the same time, by serializing the wormhole
|
||||||
|
|
||||||
|
What's good about dilated wormholes?:
|
||||||
|
|
||||||
|
* they support bulk data transfer
|
||||||
|
* you get flow control (backpressure), and provide IProducer/IConsumer
|
||||||
|
* throughput is faster: no store-and-forward step
|
||||||
|
|
||||||
|
Use non-dilated wormholes when your application only needs to exchange a
|
||||||
|
couple of messages, for example to set up public keys or provision access
|
||||||
|
tokens. Use a dilated wormhole to move large files.
|
||||||
|
|
||||||
|
Dilated wormholes can provide multiple "channels": these are multiplexed
|
||||||
|
through the single (encrypted) TCP connection. Each channel is a separate
|
||||||
|
stream (offering IProducer/IConsumer)
|
||||||
|
|
||||||
|
To create a channel, call `c = w.create_channel()` on a dilated wormhole. The
|
||||||
|
"channel ID" can be obtained with `c.get_id()`. This ID will be a short
|
||||||
|
(unicode) string, which can be sent to the other side via a normal
|
||||||
|
`w.send()`, or any other means. On the other side, use `c =
|
||||||
|
w.open_channel(channel_id)` to get a matching channel object.
|
||||||
|
|
||||||
|
Then use `c.send(data)` and `d=c.when_received()` to exchange data, or wire
|
||||||
|
them up with `c.registerProducer()`. Note that channels do not close until
|
||||||
|
the wormhole connection is closed, so they do not have separate `close()`
|
||||||
|
methods or events. Therefore if you plan to send files through them, you'll
|
||||||
|
need to inform the recipient ahead of time about how many bytes to expect.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user