transfer.timeout: Support configurable timeouts for dead clients
Broken (or simply evil) clients can open a command and hang forever, without exchanging packets with us. These connections consume a work thread from the thread pool, and tie up server memory that could be used to assist another client. By configuring transfer.timeout in gerrit.config a site administrator can now limit how long their server will wait for a single IO operation to complete before disconnecting a client with a timeout error. The timeout is currently disabled by default because it requires spinning up (and tearing down) a thread for each command executed. The thread exists only to count-down the timeout period and interrupt the blocked IO operation on the real work thread. Hopefully we can modify JGit to either support non-blocking, asynchronous IO here, or to permit using timer thread pools, to reduce the thread overhead involved with setting up a timeout for a network socket. Change-Id: Ic1608d4905082bb0639c2a0b35fd3bd9a6fccd43 Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -18,12 +18,14 @@ import com.google.gerrit.reviewdb.Account;
|
||||
import com.google.gerrit.server.IdentifiedUser;
|
||||
import com.google.gerrit.server.git.ReceiveCommits;
|
||||
import com.google.gerrit.sshd.AbstractGitCommand;
|
||||
import com.google.gerrit.sshd.TransferConfig;
|
||||
import com.google.inject.Inject;
|
||||
|
||||
import org.eclipse.jgit.transport.ReceivePack;
|
||||
import org.kohsuke.args4j.Option;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InterruptedIOException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -38,6 +40,9 @@ final class Receive extends AbstractGitCommand {
|
||||
@Inject
|
||||
private IdentifiedUser.GenericFactory identifiedUserFactory;
|
||||
|
||||
@Inject
|
||||
private TransferConfig config;
|
||||
|
||||
private final Set<Account.Id> reviewerId = new HashSet<Account.Id>();
|
||||
private final Set<Account.Id> ccId = new HashSet<Account.Id>();
|
||||
|
||||
@@ -68,7 +73,12 @@ final class Receive extends AbstractGitCommand {
|
||||
|
||||
final ReceivePack rp = receive.getReceivePack();
|
||||
rp.setRefLogIdent(currentUser.newRefLogIdent());
|
||||
rp.receive(in, out, err);
|
||||
rp.setTimeout(config.getTimeout());
|
||||
try {
|
||||
rp.receive(in, out, err);
|
||||
} catch (InterruptedIOException err) {
|
||||
throw new Failure(128, "fatal: client IO read/write timeout", err);
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyProjectVisible(final String type, final Set<Account.Id> who)
|
||||
|
Reference in New Issue
Block a user