daemon: Add --ketch=LEADER flag
Experimental flag to turn on the KetchLeader within this daemon JVM. This is a manually elected leader process, set from the command line. Remote followers for each repository are configured per-repository using remote sections with ketch-type = FULL. For example: Manually elected leader's $GIT_DIR/config: [ketch] name = A [remote "A"] ketch-type = FULL [remote "B"] url = git://127.0.0.1:9421/sample.git ketch-type = FULL [remote "C"] url = git://127.0.0.1:9422/sample.git ketch-type = FULL Replica B and C daemons: git daemon \ --export-all \ --enable=receive-pack \ --listen=127.0.0.1 --port=9421 \ --base-path=$HOME/ketch_test/follower_one \ $HOME/ketch_test/follower_one & git daemon \ --export-all \ --enable=receive-pack \ --listen=127.0.0.1 --port=9422 \ --base-path=$HOME/ketch_test/follower_two \ $HOME/ketch_test/follower_two & Change-Id: I165f85970a77e16b5263115290d685d8a00566f5
This commit is contained in:
parent
1f9d205043
commit
da5ef91ad0
|
@ -19,6 +19,7 @@ Import-Package: org.apache.commons.compress.archivers;version="[1.3,2.0)",
|
|||
org.eclipse.jgit.dircache;version="[4.2.0,4.3.0)",
|
||||
org.eclipse.jgit.errors;version="[4.2.0,4.3.0)",
|
||||
org.eclipse.jgit.gitrepo;version="[4.2.0,4.3.0)",
|
||||
org.eclipse.jgit.internal.ketch;version="[4.2.0,4.3.0)",
|
||||
org.eclipse.jgit.internal.storage.file;version="[4.2.0,4.3.0)",
|
||||
org.eclipse.jgit.internal.storage.pack;version="[4.2.0,4.3.0)",
|
||||
org.eclipse.jgit.internal.storage.reftree;version="[4.2.0,4.3.0)",
|
||||
|
|
|
@ -45,18 +45,29 @@
|
|||
|
||||
import java.io.File;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.URISyntaxException;
|
||||
import java.text.MessageFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executors;
|
||||
|
||||
import org.eclipse.jgit.internal.ketch.KetchLeader;
|
||||
import org.eclipse.jgit.internal.ketch.KetchLeaderCache;
|
||||
import org.eclipse.jgit.internal.ketch.KetchPreReceive;
|
||||
import org.eclipse.jgit.internal.ketch.KetchSystem;
|
||||
import org.eclipse.jgit.internal.ketch.KetchText;
|
||||
import org.eclipse.jgit.lib.Repository;
|
||||
import org.eclipse.jgit.pgm.internal.CLIText;
|
||||
import org.eclipse.jgit.storage.file.FileBasedConfig;
|
||||
import org.eclipse.jgit.storage.file.WindowCacheConfig;
|
||||
import org.eclipse.jgit.storage.pack.PackConfig;
|
||||
import org.eclipse.jgit.transport.DaemonClient;
|
||||
import org.eclipse.jgit.transport.DaemonService;
|
||||
import org.eclipse.jgit.transport.ReceivePack;
|
||||
import org.eclipse.jgit.transport.resolver.FileResolver;
|
||||
import org.eclipse.jgit.transport.resolver.ReceivePackFactory;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
|
||||
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
|
||||
import org.eclipse.jgit.util.FS;
|
||||
import org.kohsuke.args4j.Argument;
|
||||
import org.kohsuke.args4j.Option;
|
||||
|
@ -90,6 +101,13 @@ class Daemon extends TextBuiltin {
|
|||
@Option(name = "--export-all", usage = "usage_exportWithoutGitDaemonExportOk")
|
||||
boolean exportAll;
|
||||
|
||||
@Option(name = "--ketch")
|
||||
KetchServerType ketchServerType;
|
||||
|
||||
enum KetchServerType {
|
||||
LEADER;
|
||||
}
|
||||
|
||||
@Argument(required = true, metaVar = "metaVar_directory", usage = "usage_directoriesToExport")
|
||||
final List<File> directory = new ArrayList<File>();
|
||||
|
||||
|
@ -146,7 +164,9 @@ protected void run() throws Exception {
|
|||
service(d, n).setOverridable(true);
|
||||
for (final String n : forbidOverride)
|
||||
service(d, n).setOverridable(false);
|
||||
|
||||
if (ketchServerType == KetchServerType.LEADER) {
|
||||
startKetchLeader(d);
|
||||
}
|
||||
d.start();
|
||||
outw.println(MessageFormat.format(CLIText.get().listeningOn, d.getAddress()));
|
||||
}
|
||||
|
@ -159,4 +179,29 @@ private static DaemonService service(
|
|||
throw die(MessageFormat.format(CLIText.get().serviceNotSupported, n));
|
||||
return svc;
|
||||
}
|
||||
|
||||
private void startKetchLeader(org.eclipse.jgit.transport.Daemon daemon) {
|
||||
KetchSystem system = new KetchSystem();
|
||||
final KetchLeaderCache leaders = new KetchLeaderCache(system);
|
||||
final ReceivePackFactory<DaemonClient> factory;
|
||||
|
||||
factory = daemon.getReceivePackFactory();
|
||||
daemon.setReceivePackFactory(new ReceivePackFactory<DaemonClient>() {
|
||||
@Override
|
||||
public ReceivePack create(DaemonClient req, Repository repo)
|
||||
throws ServiceNotEnabledException,
|
||||
ServiceNotAuthorizedException {
|
||||
ReceivePack rp = factory.create(req, repo);
|
||||
KetchLeader leader;
|
||||
try {
|
||||
leader = leaders.get(repo);
|
||||
} catch (URISyntaxException err) {
|
||||
throw new ServiceNotEnabledException(
|
||||
KetchText.get().invalidFollowerUri, err);
|
||||
}
|
||||
rp.setPreReceiveHook(new KetchPreReceive(leader));
|
||||
return rp;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
accepted=accepted.
|
||||
cannotFetchFromLocalReplica=cannot fetch from LocalReplica
|
||||
failed=failed!
|
||||
invalidFollowerUri=invalid follower URI
|
||||
leaderFailedToStore=leader failed to store
|
||||
localReplicaRequired=LocalReplica instance is required
|
||||
mismatchedTxnNamespace=mismatched txnNamespace; expected {0} found {1}
|
||||
|
|
|
@ -57,6 +57,7 @@ public static KetchText get() {
|
|||
/***/ public String accepted;
|
||||
/***/ public String cannotFetchFromLocalReplica;
|
||||
/***/ public String failed;
|
||||
/***/ public String invalidFollowerUri;
|
||||
/***/ public String leaderFailedToStore;
|
||||
/***/ public String localReplicaRequired;
|
||||
/***/ public String mismatchedTxnNamespace;
|
||||
|
|
|
@ -255,6 +255,16 @@ public void setUploadPackFactory(UploadPackFactory<DaemonClient> factory) {
|
|||
uploadPackFactory = (UploadPackFactory<DaemonClient>) UploadPackFactory.DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the factory used to construct per-request ReceivePack.
|
||||
*
|
||||
* @return the factory.
|
||||
* @since 4.2
|
||||
*/
|
||||
public ReceivePackFactory<DaemonClient> getReceivePackFactory() {
|
||||
return receivePackFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the factory to construct and configure per-request ReceivePack.
|
||||
*
|
||||
|
|
Loading…
Reference in New Issue