Fossil SCM

checkin/e4180437441b1f1c074bc11e587011441c358ed664b247202b933990bb130318

2 months, 1 week ago by drh

clone and sync often hang or appear to hang on links with highly variable latency, sometimes doing so many retries the transfer rate is infeasibly slow and at others spinning on reads that never complete. Both git and mercurial cope well with the same network doing very similar transfers, seemingly due to their protocol design and implementatin. The fixes here improve the fossil implementation somewhat. Everything here was tested with the fossil HTTP 1.1 patch.

  • Set TCP_NODELAY on the client socket

The sync protocol interleaves small control writes with bulk transfer, and with the Nagle algorithm active those small writes are held waiting for ACKs; combined with the peer's delayed ACKs this throttles throughput badly on higher-latency paths. Disabling Nagle can give a 10x throughput improvement. This is what curl and many other HTTP clients do (Git uses curl.)

  • No blocking forever on TLS reads and writes

After the TLS handshake the socket is switched to non-blocking mode. ssl_send() and ssl_receive() now wait for readiness with poll() and a timeout, and abandon a connection that has stopped communicating or been reset. The blocking socket remains during the handshake so behaviour is unchanged.

  • Retry on EINTR

If a signal interrupts recv()/send() we now return -1/EINTR. This seems to be an improvement on treating the signal as end-of-stream and silently truncating the transfer.

  • Report truncated replies as errors

When a read makes no progress due to a stalled or half-closed connection we now return NULL to indicate end of input. This means we no longer try to parse partial responses.

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button