aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn Pearce <spearce@spearce.org>2016-01-12 21:55:43 -0800
committerShawn Pearce <spearce@spearce.org>2016-01-19 23:05:28 -0800
commitda5ef91ad0c7021142f184bf24abafc0895e3446 (patch)
tree14e8fc3ebb8993108f27f718c51ae6ba553bbd10
parent1f9d2050434f7ad25e06f44c1842dd365d6ec539 (diff)
downloadjgit-da5ef91ad0c7021142f184bf24abafc0895e3446.tar.gz
jgit-da5ef91ad0c7021142f184bf24abafc0895e3446.zip
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
-rw-r--r--org.eclipse.jgit.pgm/META-INF/MANIFEST.MF1
-rw-r--r--org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java47
-rw-r--r--org.eclipse.jgit/resources/org/eclipse/jgit/internal/ketch/KetchText.properties1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchText.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java10
5 files changed, 59 insertions, 1 deletions
diff --git a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
index 9dc6aea16f..bc9205c7ce 100644
--- a/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
+++ b/org.eclipse.jgit.pgm/META-INF/MANIFEST.MF
@@ -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)",
diff --git a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
index 04182d6dbe..03f3fac0b6 100644
--- a/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
+++ b/org.eclipse.jgit.pgm/src/org/eclipse/jgit/pgm/Daemon.java
@@ -45,18 +45,29 @@ package org.eclipse.jgit.pgm;
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 @@ class Daemon extends TextBuiltin {
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 @@ class Daemon extends TextBuiltin {
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;
+ }
+ });
+ }
} \ No newline at end of file
diff --git a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/ketch/KetchText.properties b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/ketch/KetchText.properties
index 3817fb93cc..1fbb7cb3b5 100644
--- a/org.eclipse.jgit/resources/org/eclipse/jgit/internal/ketch/KetchText.properties
+++ b/org.eclipse.jgit/resources/org/eclipse/jgit/internal/ketch/KetchText.properties
@@ -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}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchText.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchText.java
index da85c0112d..b6c3bc92c5 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchText.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/ketch/KetchText.java
@@ -57,6 +57,7 @@ public class KetchText extends TranslationBundle {
/***/ public String accepted;
/***/ public String cannotFetchFromLocalReplica;
/***/ public String failed;
+ /***/ public String invalidFollowerUri;
/***/ public String leaderFailedToStore;
/***/ public String localReplicaRequired;
/***/ public String mismatchedTxnNamespace;
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java
index d9e0b937e8..2593ba556d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/Daemon.java
@@ -256,6 +256,16 @@ public class Daemon {
}
/**
+ * 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.
*
* @param factory