This fixes#145. I thought it would add a roundtrip, but it turns out that
websockets were already adding the same delay, so I can't avoid it without
switching from websockets to raw TCP. Closes#145.
This renames all the existing API methods, to use a consistent
"d=get_XYZ()" (for Deferred mode) or "dg.wormhole_got_XYZ()" (for Delegated
mode). It updates cmd_send/cmd_receive/cmd_ssh to use the new API.
Since we now have get_welcome(), apps handle the Welcome message with a
Deferred callback instead of registering a "welcome handler". This lets us
make sure we've finished printing any server message-of-the-day or "you
should update your client" message to stdout before using stdio to ask for
the wormhole code. (Previously, the code-input prompt was overwritten by the
server message, and it was ugly). refs #145. This approach adds an extra
roundtrip to the receiver, but we can fix that (see #145 for details).
Because of that change, the server-is-being-slow message is printed at a
slightly different time, so those tests needed some extra work to exercise it
properly.
The code in util.py can tolerate a missing os.statvfs, but the code which
tests that code's ability to tolerate a missing os.statvfs was itself unable
to tolerate a missing os.statvfs. Sigh.
Apparently there's an intermittent condition in tests that follows this path.
We used to ignore unrecognized states, but to improve test coverage I added a
clause to catch them, and now that clause is happening where I didn't expect
it.
This fixes the case where "wormhole send" would wait forever (upon network
error) instead of terminating with a useful error message.
Testing this will have to wait until we land the branch that abandons the
wormhole if the first connection fails, since that's the easiest way to
provoke a network error before when_code() has fired.
I think we're better off without this: the CLI commands propagate the Failure
up to their callers (rather than eating it silently), the callers are using
task.react (which reacts to Failures by exiting with rc!=0), so nothing
should get lost. And doing an extra log.err() just creates more cleanup work
for test cases to flush, and makes the CLI commands double-print the any
errors (maybe task.react also points logging at stderr?).
This completely rewrites the client, splitting everything into many (13!)
small-ish state machines, merging about 5 months of work. This will enable
the following new features (none of which are fully implemented yet):
* survive the rendezvous server connection being lost, if we can reconnect
* learn the wordlist from the server, after claiming the nameplate, to enable
i18n wordlists (sender chooses language, receiver tab-completes on the
matching wordlist)
* likewise we can learn the code-length (number of words) from the server,
although this needs more thought before we can make it safe
* new "Delegated Mode" API, with callbacks instead of Deferreds
* properly serializable Wormhole state
* "journaled mode": synchronzing outbound messages with application state
checkpoints to provide robust behavior in the face of frequent and
uncoordinated shutdown
* making progress even when neither side is connected at the same time
* code-completion with non-readline frontends (e.g. GUI wordlist-dropdown)
User-visible changes from this rewrite:
* wormhole receive: if you use tab-completion, you can only set the nameplate
once, after which we've claimed that channel and are stuck with it until
the process exits. This means you can't type "5-<TAB><DEL><DEL>3-", because
we've already committed to a nameplate of "5". So initial typos are more of
a problem now. The client will show you an exception, but then you must
Control-C the process to exit.
* the "you should upgrade to a newer version" message now overlaps with the
code-input prompt, which is annoying (I hope to fix this before a release)
* networking problems that prevent a connection to the rendezvous server will
cause silent hangs (until I fix this too)
New docs:
* the docs/ directory now contains descriptions of the various
client-to-server and client-to-client protocols we use (none of which
changed)
* docs/api.md now has a comprehensive description of the API (which is still
subject to change)
* docs/state-machines/ contains DOT-format descriptions of each new state
machine, although running "automat-visualize wormhole" will build
more-accurate (but less-informative) diagrams of the actual
implementations
refs #42