We had a very nasty problem: handshakes were serial so incoming
dials would wait for each other to finish handshaking. this was
particularly problematic when handshakes hung-- nodes would not
recover quickly. This led to gateways not bootstrapping peers
fast enough.
The approach taken here is to do what crypto/tls does:
defer the handshake until Read/Write[1]. There are a number of
reasons why this is _the right thing to do_:
- it delays handshaking until it is known to be necessary (doing io)
- it "accepts" before the handshake, getting the handshake out of the
critical path entirely.
- it defers to the user's parallelization of conn handling. users
must implement this in some way already so use that, instead of
picking constants surely to be wrong (how many handshakes to run
in parallel?)
[0] http://golang.org/src/crypto/tls/conn.go#L886
Setup a three-level graph:
a -(child)-> b -(grandchild)-> c
and then try and resolve:
/ipfs/<hash-of-a>/child/grandchild
Before 10669e8b (path/resolver: Fix recursive path resolution,
2015-05-08) this failed with:
resolver_test.go:71: no link named "grandchild" under QmSomeRandomHash
The boilerplate for this test is from pin/pin_test.go, and I make no
claims that it's the best way to setup the test graph ;).
I'm not entirely clear on Go's scoping (there's some text I can't
quite parse here [1]), but it seems like the := version (because this
is the first time we use 'err') was masking the function-level 'nd'
just for this if block. That means that after we get out of the if
block and return to the start of the for-loop for the next pass,
nd.Links would still be pointing at the original object's links.
This commit drops the :=, which fixes the earlier:
$ ipfs ls QmXX7YRpU7nNBKfw75VG7Y1c3GwpSAGHRev67XVPgZFv9R/static/css
Error: no link named "css" under QmXX7YRpU7nNBKfw75VG7Y1c3GwpSAGHRev67XVPgZFv9R
so we get the intended:
$ ipfs ls QmXX7YRpU7nNBKfw75VG7Y1c3GwpSAGHRev67XVPgZFv9R/static/css
Qme4r3eA4h1revFBgCEv1HF1U7sLL4vvAyzRLWJhCFhwg2 7051 style.css
It also means we're probably missing (or are unreliably using) a
multi-level-path-resolving test.
[1]: https://golang.org/ref/spec#Declarations_and_scope
commands/object: remove objectData() and objectLinks() helpers
resolver: added context parameters
sharness: $HASH carried the \r from the http protocol with
sharness: write curl output to individual files
http gw: break PUT handler until PR#1191