Browse Source

Merge branch 'ticket/89' into develop

tags/v1.6.0
James Moger 10 years ago
parent
commit
020f7e4b06

+ 9
- 1
src/main/java/com/gitblit/manager/ServicesManager.java View File

import com.gitblit.utils.IdGenerator; import com.gitblit.utils.IdGenerator;
import com.gitblit.utils.StringUtils; import com.gitblit.utils.StringUtils;
import com.gitblit.utils.TimeUtils; import com.gitblit.utils.TimeUtils;
import com.gitblit.utils.WorkQueue;


/** /**
* Services manager manages long-running services/processes that either have no * Services manager manages long-running services/processes that either have no


private final IGitblit gitblit; private final IGitblit gitblit;


private final IdGenerator idGenerator;

private final WorkQueue workQueue;

private FanoutService fanoutService; private FanoutService fanoutService;


private GitDaemon gitDaemon; private GitDaemon gitDaemon;
public ServicesManager(IGitblit gitblit) { public ServicesManager(IGitblit gitblit) {
this.settings = gitblit.getSettings(); this.settings = gitblit.getSettings();
this.gitblit = gitblit; this.gitblit = gitblit;
this.idGenerator = new IdGenerator();
this.workQueue = new WorkQueue(idGenerator, 1);
} }


@Override @Override
if (sshDaemon != null) { if (sshDaemon != null) {
sshDaemon.stop(); sshDaemon.stop();
} }
workQueue.stop();
return this; return this;
} }


String bindInterface = settings.getString(Keys.git.sshBindInterface, "localhost"); String bindInterface = settings.getString(Keys.git.sshBindInterface, "localhost");
if (port > 0) { if (port > 0) {
try { try {
sshDaemon = new SshDaemon(gitblit, new IdGenerator());
sshDaemon = new SshDaemon(gitblit, workQueue);
sshDaemon.start(); sshDaemon.start();
} catch (IOException e) { } catch (IOException e) {
sshDaemon = null; sshDaemon = null;

+ 4
- 3
src/main/java/com/gitblit/transport/ssh/SshDaemon.java View File

import com.gitblit.Keys; import com.gitblit.Keys;
import com.gitblit.manager.IGitblit; import com.gitblit.manager.IGitblit;
import com.gitblit.transport.ssh.commands.SshCommandFactory; import com.gitblit.transport.ssh.commands.SshCommandFactory;
import com.gitblit.utils.IdGenerator;
import com.gitblit.utils.JnaUtils; import com.gitblit.utils.JnaUtils;
import com.gitblit.utils.StringUtils; import com.gitblit.utils.StringUtils;
import com.gitblit.utils.WorkQueue;
import com.google.common.io.Files; import com.google.common.io.Files;


/** /**
* Construct the Gitblit SSH daemon. * Construct the Gitblit SSH daemon.
* *
* @param gitblit * @param gitblit
* @param workQueue
*/ */
public SshDaemon(IGitblit gitblit, IdGenerator idGenerator) {
public SshDaemon(IGitblit gitblit, WorkQueue workQueue) {
this.gitblit = gitblit; this.gitblit = gitblit;


IStoredSettings settings = gitblit.getSettings(); IStoredSettings settings = gitblit.getSettings();
sshd.setSessionFactory(new SshServerSessionFactory()); sshd.setSessionFactory(new SshServerSessionFactory());
sshd.setFileSystemFactory(new DisabledFilesystemFactory()); sshd.setFileSystemFactory(new DisabledFilesystemFactory());
sshd.setTcpipForwardingFilter(new NonForwardingFilter()); sshd.setTcpipForwardingFilter(new NonForwardingFilter());
sshd.setCommandFactory(new SshCommandFactory(gitblit, idGenerator));
sshd.setCommandFactory(new SshCommandFactory(gitblit, workQueue));
sshd.setShellFactory(new WelcomeShell(settings)); sshd.setShellFactory(new WelcomeShell(settings));


// Set the server id. This can be queried with: // Set the server id. This can be queried with:

+ 17
- 6
src/main/java/com/gitblit/transport/ssh/commands/BaseCommand.java View File

import org.apache.sshd.server.ExitCallback; import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.SessionAware; import org.apache.sshd.server.SessionAware;
import org.apache.sshd.server.session.ServerSession; import org.apache.sshd.server.session.ServerSession;
import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.CmdLineException; import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.Option;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;


import com.gitblit.Keys; import com.gitblit.Keys;
import com.gitblit.utils.IdGenerator;
import com.gitblit.utils.StringUtils; import com.gitblit.utils.StringUtils;
import com.gitblit.utils.WorkQueue; import com.gitblit.utils.WorkQueue;
import com.gitblit.utils.WorkQueue.CancelableRunnable; import com.gitblit.utils.WorkQueue.CancelableRunnable;
/** The task, as scheduled on a worker thread. */ /** The task, as scheduled on a worker thread. */
private final AtomicReference<Future<?>> task; private final AtomicReference<Future<?>> task;


private final WorkQueue.Executor executor;
private WorkQueue workQueue;


public BaseCommand() { public BaseCommand() {
task = Atomics.newReference(); task = Atomics.newReference();
IdGenerator gen = new IdGenerator();
WorkQueue w = new WorkQueue(gen);
this.executor = w.getDefaultQueue();
} }


@Override @Override
@Override @Override
public void destroy() { public void destroy() {
log.debug("destroying " + getClass().getName()); log.debug("destroying " + getClass().getName());
Future<?> future = task.getAndSet(null);
if (future != null && !future.isDone()) {
future.cancel(true);
}
session = null; session = null;
ctx = null; ctx = null;
} }


protected void provideStateTo(final BaseCommand cmd) { protected void provideStateTo(final BaseCommand cmd) {
cmd.setContext(ctx); cmd.setContext(ctx);
cmd.setWorkQueue(workQueue);
cmd.setInputStream(in); cmd.setInputStream(in);
cmd.setOutputStream(out); cmd.setOutputStream(out);
cmd.setErrorStream(err); cmd.setErrorStream(err);
cmd.setExitCallback(exit); cmd.setExitCallback(exit);
} }


public WorkQueue getWorkQueue() {
return workQueue;
}

public void setWorkQueue(WorkQueue workQueue) {
this.workQueue = workQueue;
}

public void setContext(SshCommandContext ctx) { public void setContext(SshCommandContext ctx) {
this.ctx = ctx; this.ctx = ctx;
} }
*/ */
protected void startThread(final CommandRunnable thunk) { protected void startThread(final CommandRunnable thunk) {
final TaskThunk tt = new TaskThunk(thunk); final TaskThunk tt = new TaskThunk(thunk);
task.set(executor.submit(tt));
task.set(workQueue.getDefaultQueue().submit(tt));
} }


/** Thrown from {@link CommandRunnable#run()} with client message and code. */ /** Thrown from {@link CommandRunnable#run()} with client message and code. */

+ 1
- 0
src/main/java/com/gitblit/transport/ssh/commands/DispatchCommand.java View File



try { try {
dispatcher.setContext(getContext()); dispatcher.setContext(getContext());
dispatcher.setWorkQueue(getWorkQueue());
dispatcher.setup(); dispatcher.setup();
if (dispatcher.commands.isEmpty() && dispatcher.dispatchers.isEmpty()) { if (dispatcher.commands.isEmpty() && dispatcher.dispatchers.isEmpty()) {
log.debug(MessageFormat.format("excluding empty dispatcher {0} for {1}", log.debug(MessageFormat.format("excluding empty dispatcher {0} for {1}",

+ 3
- 1
src/main/java/com/gitblit/transport/ssh/commands/RootDispatcher.java View File

import com.gitblit.transport.ssh.SshDaemonClient; import com.gitblit.transport.ssh.SshDaemonClient;
import com.gitblit.transport.ssh.git.GitDispatcher; import com.gitblit.transport.ssh.git.GitDispatcher;
import com.gitblit.transport.ssh.keys.KeysDispatcher; import com.gitblit.transport.ssh.keys.KeysDispatcher;
import com.gitblit.utils.WorkQueue;


/** /**
* The root dispatcher is the dispatch command that handles registering all * The root dispatcher is the dispatch command that handles registering all


private Logger log = LoggerFactory.getLogger(getClass()); private Logger log = LoggerFactory.getLogger(getClass());


public RootDispatcher(IGitblit gitblit, SshDaemonClient client, String cmdLine) {
public RootDispatcher(IGitblit gitblit, SshDaemonClient client, String cmdLine, WorkQueue workQueue) {
super(); super();
setContext(new SshCommandContext(gitblit, client, cmdLine)); setContext(new SshCommandContext(gitblit, client, cmdLine));
setWorkQueue(workQueue);


register(VersionCommand.class); register(VersionCommand.class);
register(GitDispatcher.class); register(GitDispatcher.class);

+ 4
- 4
src/main/java/com/gitblit/transport/ssh/commands/SshCommandFactory.java View File

import com.gitblit.Keys; import com.gitblit.Keys;
import com.gitblit.manager.IGitblit; import com.gitblit.manager.IGitblit;
import com.gitblit.transport.ssh.SshDaemonClient; import com.gitblit.transport.ssh.SshDaemonClient;
import com.gitblit.utils.IdGenerator;
import com.gitblit.utils.WorkQueue; import com.gitblit.utils.WorkQueue;
import com.google.common.util.concurrent.Atomics; import com.google.common.util.concurrent.Atomics;
import com.google.common.util.concurrent.ThreadFactoryBuilder; import com.google.common.util.concurrent.ThreadFactoryBuilder;
public class SshCommandFactory implements CommandFactory { public class SshCommandFactory implements CommandFactory {
private static final Logger logger = LoggerFactory.getLogger(SshCommandFactory.class); private static final Logger logger = LoggerFactory.getLogger(SshCommandFactory.class);


private final WorkQueue workQueue;
private final IGitblit gitblit; private final IGitblit gitblit;
private final ScheduledExecutorService startExecutor; private final ScheduledExecutorService startExecutor;
private final ExecutorService destroyExecutor; private final ExecutorService destroyExecutor;


public SshCommandFactory(IGitblit gitblit, IdGenerator idGenerator) {
public SshCommandFactory(IGitblit gitblit, WorkQueue workQueue) {
this.gitblit = gitblit; this.gitblit = gitblit;
this.workQueue = workQueue;


int threads = gitblit.getSettings().getInteger(Keys.git.sshCommandStartThreads, 2); int threads = gitblit.getSettings().getInteger(Keys.git.sshCommandStartThreads, 2);
WorkQueue workQueue = new WorkQueue(idGenerator);
startExecutor = workQueue.createQueue(threads, "SshCommandStart"); startExecutor = workQueue.createQueue(threads, "SshCommandStart");
destroyExecutor = Executors.newSingleThreadExecutor( destroyExecutor = Executors.newSingleThreadExecutor(
new ThreadFactoryBuilder() new ThreadFactoryBuilder()
} }


public RootDispatcher createRootDispatcher(SshDaemonClient client, String commandLine) { public RootDispatcher createRootDispatcher(SshDaemonClient client, String commandLine) {
return new RootDispatcher(gitblit, client, commandLine);
return new RootDispatcher(gitblit, client, commandLine, workQueue);
} }


@Override @Override

+ 4
- 2
src/main/java/com/gitblit/utils/WorkQueue.java View File



private Executor defaultQueue; private Executor defaultQueue;
private final IdGenerator idGenerator; private final IdGenerator idGenerator;
private final int defaultQueueSize;
private final CopyOnWriteArrayList<Executor> queues; private final CopyOnWriteArrayList<Executor> queues;


public WorkQueue(final IdGenerator idGenerator) {
public WorkQueue(final IdGenerator idGenerator, final int defaultQueueSize) {
this.idGenerator = idGenerator; this.idGenerator = idGenerator;
this.defaultQueueSize = defaultQueueSize;
this.queues = new CopyOnWriteArrayList<Executor>(); this.queues = new CopyOnWriteArrayList<Executor>();
} }


/** Get the default work queue, for miscellaneous tasks. */ /** Get the default work queue, for miscellaneous tasks. */
public synchronized Executor getDefaultQueue() { public synchronized Executor getDefaultQueue() {
if (defaultQueue == null) { if (defaultQueue == null) {
defaultQueue = createQueue(1, "WorkQueue");
defaultQueue = createQueue(defaultQueueSize, "WorkQueue");
} }
return defaultQueue; return defaultQueue;
} }

Loading…
Cancel
Save