提交 e05358bf 编写于 作者: J Jesse Glick

Merge branch 'master' of git://github.com/jenkinsci/jenkins

......@@ -55,7 +55,8 @@ Upcoming changes</a>
<!-- Record your changes in the trunk here. -->
<div id="trunk" style="display:none"><!--=TRUNK-BEGIN=-->
<ul class=image>
<li class=>
<li class=rfe>
JNLP slaves are now handled through NIO-based remoting channels for better scalability.
</ul>
</div><!--=TRUNK-END=-->
......
......@@ -29,7 +29,7 @@ import hudson.remoting.PingThread;
import hudson.remoting.Pipe;
import hudson.remoting.RemoteInputStream;
import hudson.remoting.RemoteOutputStream;
import hudson.remoting.SocketInputStream;
import hudson.remoting.SocketChannelStream;
import hudson.remoting.SocketOutputStream;
import javax.crypto.SecretKey;
......@@ -201,7 +201,7 @@ public class CLI {
} else {
s = new Socket();
s.connect(clip.endpoint,3000);
out = new SocketOutputStream(s);
out = SocketChannelStream.out(s);
}
closables.add(new Closeable() {
......@@ -210,7 +210,7 @@ public class CLI {
}
});
Connection c = new Connection(new SocketInputStream(s),out);
Connection c = new Connection(SocketChannelStream.in(s),out);
switch (clip.version) {
case 1:
......
......@@ -23,8 +23,7 @@
*/
package hudson.cli;
import hudson.remoting.SocketInputStream;
import hudson.remoting.SocketOutputStream;
import hudson.remoting.SocketChannelStream;
import org.apache.commons.codec.binary.Base64;
import javax.crypto.Cipher;
......@@ -63,7 +62,7 @@ public class Connection {
public final DataOutputStream dout;
public Connection(Socket socket) throws IOException {
this(new SocketInputStream(socket),new SocketOutputStream(socket));
this(SocketChannelStream.in(socket),SocketChannelStream.out(socket));
}
public Connection(InputStream in, OutputStream out) {
......
......@@ -818,7 +818,7 @@ public abstract class Launcher {
* Kill the process when the channel is severed.
*/
@Override
protected synchronized void terminate(IOException e) {
public synchronized void terminate(IOException e) {
super.terminate(e);
ProcessTree pt = ProcessTree.get();
try {
......
......@@ -32,8 +32,10 @@ import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.BindException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.channels.ServerSocketChannel;
import java.util.logging.Level;
import java.util.logging.Logger;
......@@ -55,7 +57,7 @@ import java.util.logging.Logger;
*/
public final class TcpSlaveAgentListener extends Thread {
private final ServerSocket serverSocket;
private final ServerSocketChannel serverSocket;
private volatile boolean shuttingDown;
public final int configuredPort;
......@@ -67,7 +69,8 @@ public final class TcpSlaveAgentListener extends Thread {
public TcpSlaveAgentListener(int port) throws IOException {
super("TCP slave agent listener port="+port);
try {
serverSocket = new ServerSocket(port);
serverSocket = ServerSocketChannel.open();
serverSocket.socket().bind(new InetSocketAddress(port));
} catch (BindException e) {
throw (BindException)new BindException("Failed to listen on port "+port+" because it's already in use.").initCause(e);
}
......@@ -82,7 +85,7 @@ public final class TcpSlaveAgentListener extends Thread {
* Gets the TCP port number in which we are listening.
*/
public int getPort() {
return serverSocket.getLocalPort();
return serverSocket.socket().getLocalPort();
}
@Override
......@@ -90,7 +93,7 @@ public final class TcpSlaveAgentListener extends Thread {
try {
// the loop eventually terminates when the socket is closed.
while (true) {
Socket s = serverSocket.accept();
Socket s = serverSocket.accept().socket();
// this prevents a connection from silently terminated by the router in between or the other peer
// and that goes without unnoticed. However, the time out is often very long (for example 2 hours
......
......@@ -4,9 +4,13 @@ import hudson.Extension;
import hudson.model.Computer;
import hudson.remoting.Channel;
import hudson.remoting.Channel.Mode;
import hudson.remoting.ChannelBuilder;
import jenkins.AgentProtocol;
import jenkins.model.Jenkins;
import jenkins.slaves.NioChannelSelector;
import org.jenkinsci.remoting.nio.NioChannelHub;
import javax.inject.Inject;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedWriter;
......@@ -23,6 +27,9 @@ import java.net.Socket;
*/
@Extension
public class CliProtocol extends AgentProtocol {
@Inject
NioChannelSelector nio;
@Override
public String getName() {
return "CLI-connect";
......@@ -30,13 +37,23 @@ public class CliProtocol extends AgentProtocol {
@Override
public void handle(Socket socket) throws IOException, InterruptedException {
new Handler(socket).run();
new Handler(nio.getHub(),socket).run();
}
protected static class Handler {
protected final NioChannelHub hub;
protected final Socket socket;
/**
* @deprecated as of 1.559
* Use {@link #Handler(NioChannelHub, Socket)}
*/
public Handler(Socket socket) {
this(null,socket);
}
public Handler(NioChannelHub hub, Socket socket) {
this.hub = hub;
this.socket = socket;
}
......@@ -47,9 +64,21 @@ public class CliProtocol extends AgentProtocol {
}
protected void runCli(Connection c) throws IOException, InterruptedException {
Channel channel = new Channel("CLI channel from " + socket.getInetAddress(),
Computer.threadPoolForRemoting, Mode.BINARY,
new BufferedInputStream(c.in), new BufferedOutputStream(c.out), null, true, Jenkins.getInstance().pluginManager.uberClassLoader);
ChannelBuilder cb;
String name = "CLI channel from " + socket.getInetAddress();
// Connection can contain cipher wrapper, which can't be NIO-ed.
// if (hub!=null)
// cb = hub.newChannelBuilder(name, Computer.threadPoolForRemoting);
// else
cb = new ChannelBuilder(name, Computer.threadPoolForRemoting);
Channel channel = cb
.withMode(Mode.BINARY)
.withRestricted(true)
.withBaseLoader(Jenkins.getInstance().pluginManager.uberClassLoader)
.build(new BufferedInputStream(c.in), new BufferedOutputStream(c.out));
channel.setProperty(CliEntryPoint.class.getName(),new CliManagerImpl(channel));
channel.join();
}
......
......@@ -2,6 +2,7 @@ package hudson.cli;
import hudson.Extension;
import jenkins.model.Jenkins;
import org.jenkinsci.remoting.nio.NioChannelHub;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
......@@ -28,14 +29,22 @@ public class CliProtocol2 extends CliProtocol {
@Override
public void handle(Socket socket) throws IOException, InterruptedException {
new Handler2(socket).run();
new Handler2(nio.getHub(), socket).run();
}
protected static class Handler2 extends Handler {
/**
* @deprecated as of 1.559
* Use {@link #Handler2(NioChannelHub, Socket)}
*/
public Handler2(Socket socket) {
super(socket);
}
public Handler2(NioChannelHub hub, Socket socket) {
super(hub, socket);
}
@Override
public void run() throws IOException, InterruptedException {
try {
......
......@@ -108,6 +108,7 @@ public abstract class ItemGroupMixIn {
item = (V) Items.load( parent, subdir );
}else{
Logger.getLogger( ItemGroupMixIn.class.getName() ).log( Level.WARNING, "could not find file " + xmlFile.getFile());
continue;
}
} else {
item.onLoad(parent, subdir.getName());
......
......@@ -30,8 +30,7 @@ import hudson.model.Computer;
import hudson.model.TaskListener;
import hudson.remoting.Channel;
import hudson.remoting.Launcher;
import hudson.remoting.SocketInputStream;
import hudson.remoting.SocketOutputStream;
import hudson.remoting.SocketChannelStream;
import hudson.util.ClasspathBuilder;
import hudson.util.JVMBuilder;
import hudson.util.StreamCopyThread;
......@@ -73,7 +72,7 @@ public class Channels {
* Kill the process when the channel is severed.
*/
@Override
protected synchronized void terminate(IOException e) {
public synchronized void terminate(IOException e) {
super.terminate(e);
try {
proc.kill();
......@@ -109,7 +108,7 @@ public class Channels {
* Kill the process when the channel is severed.
*/
@Override
protected synchronized void terminate(IOException e) {
public synchronized void terminate(IOException e) {
super.terminate(e);
proc.destroy();
// the stderr copier should exit by itself
......@@ -205,8 +204,8 @@ public class Channels {
serverSocket.close();
return forProcess("Channel to "+displayName, Computer.threadPoolForRemoting,
new BufferedInputStream(new SocketInputStream(s)),
new BufferedOutputStream(new SocketOutputStream(s)),null,p);
new BufferedInputStream(SocketChannelStream.in(s)),
new BufferedOutputStream(SocketChannelStream.out(s)),null,p);
}
......
......@@ -2,18 +2,18 @@ package jenkins.slaves;
import hudson.AbortException;
import hudson.Extension;
import hudson.model.Computer;
import hudson.remoting.Channel;
import hudson.remoting.Channel.Listener;
import hudson.remoting.ChannelBuilder;
import hudson.remoting.Engine;
import hudson.remoting.SocketInputStream;
import hudson.remoting.SocketOutputStream;
import hudson.slaves.SlaveComputer;
import jenkins.AgentProtocol;
import jenkins.model.Jenkins;
import jenkins.security.HMACConfidentialKey;
import org.jenkinsci.remoting.nio.NioChannelHub;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import javax.inject.Inject;
import java.io.BufferedWriter;
import java.io.DataInputStream;
import java.io.DataOutputStream;
......@@ -55,6 +55,9 @@ import java.util.logging.Logger;
*/
@Extension
public class JnlpSlaveAgentProtocol extends AgentProtocol {
@Inject
NioChannelSelector hub;
@Override
public String getName() {
return "JNLP-connect";
......@@ -62,10 +65,11 @@ public class JnlpSlaveAgentProtocol extends AgentProtocol {
@Override
public void handle(Socket socket) throws IOException, InterruptedException {
new Handler(socket).run();
new Handler(hub.getHub(),socket).run();
}
protected static class Handler {
protected final NioChannelHub hub;
protected final Socket socket;
/**
......@@ -82,7 +86,16 @@ public class JnlpSlaveAgentProtocol extends AgentProtocol {
*/
protected final PrintWriter out;
/**
* @deprecated as of 1.559
* Use {@link #Handler(NioChannelHub, Socket)}
*/
public Handler(Socket socket) throws IOException {
this(null,socket);
}
public Handler(NioChannelHub hub, Socket socket) throws IOException {
this.hub = hub;
this.socket = socket;
in = new DataInputStream(socket.getInputStream());
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(),"UTF-8")),true);
......@@ -121,7 +134,14 @@ public class JnlpSlaveAgentProtocol extends AgentProtocol {
logw.println("JNLP agent connected from "+ socket.getInetAddress());
try {
computer.setChannel(new BufferedInputStream(new SocketInputStream(socket)), new BufferedOutputStream(new SocketOutputStream(socket)), log,
ChannelBuilder cb;
if (hub==null)
cb = new ChannelBuilder(nodeName, Computer.threadPoolForRemoting);
else
cb = hub.newChannelBuilder(nodeName, Computer.threadPoolForRemoting);
computer.setChannel(cb.withHeaderStream(log).build(socket), log,
new Listener() {
@Override
public void onClosed(Channel channel, IOException cause) {
......
......@@ -7,6 +7,7 @@ import hudson.remoting.Channel;
import hudson.remoting.Engine;
import hudson.slaves.SlaveComputer;
import jenkins.model.Jenkins;
import org.jenkinsci.remoting.nio.NioChannelHub;
import java.io.ByteArrayInputStream;
import java.io.IOException;
......@@ -40,14 +41,22 @@ public class JnlpSlaveAgentProtocol2 extends JnlpSlaveAgentProtocol {
@Override
public void handle(Socket socket) throws IOException, InterruptedException {
new Handler2(socket).run();
new Handler2(hub.getHub(),socket).run();
}
protected static class Handler2 extends Handler {
/**
* @deprecated as of 1.559
* Use {@link #Handler2(NioChannelHub, Socket)}
*/
public Handler2(Socket socket) throws IOException {
super(socket);
}
public Handler2(NioChannelHub hub, Socket socket) throws IOException {
super(hub, socket);
}
/**
* Handles JNLP slave agent connection request (v2 protocol)
*/
......
package jenkins.slaves;
import hudson.Extension;
import hudson.model.Computer;
import org.jenkinsci.remoting.nio.NioChannelHub;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Singleton holder of {@link NioChannelHub}
*
* @author Kohsuke Kawaguchi
*/
@Extension
public class NioChannelSelector {
private NioChannelHub hub;
public NioChannelSelector() {
try {
if (!DISABLED) {
this.hub = new NioChannelHub(Computer.threadPoolForRemoting);
Computer.threadPoolForRemoting.submit(hub);
}
} catch (IOException e) {
LOGGER.log(Level.SEVERE, "Failed to launch NIO hub",e);
this.hub = null;
DISABLED = true;
}
}
public NioChannelHub getHub() {
return hub;
}
/**
* Escape hatch to disable use of NIO.
*/
public static boolean DISABLED = Boolean.getBoolean(NioChannelSelector.class.getName()+".disabled");
private static final Logger LOGGER = Logger.getLogger(NioChannelSelector.class.getName());
}
......@@ -172,7 +172,7 @@ THE SOFTWARE.
<dependency>
<groupId>org.jenkins-ci.main</groupId>
<artifactId>remoting</artifactId>
<version>2.37</version>
<version>2.39</version>
</dependency>
<dependency>
......
......@@ -1814,6 +1814,7 @@ function buildFormTree(form) {
}
var p;
var r;
var type = e.getAttribute("type");
if(type==null) type="";
switch(type.toLowerCase()) {
......@@ -1861,15 +1862,17 @@ function buildFormTree(form) {
break;
case "radio":
if(!e.checked) break;
while (e.name.substring(0,8)=='removeme')
e.name = e.name.substring(e.name.indexOf('_',8)+1);
r=0;
while (e.name.substring(r,r+8)=='removeme')
r = e.name.indexOf('_',r+8)+1;
p = findParent(e);
if(e.groupingNode) {
p = findParent(e);
addProperty(p, e.name, e.formDom = { value: e.value });
break;
addProperty(p, e.name.substring(r), e.formDom = { value: e.value });
} else {
addProperty(p, e.name.substring(r), e.value);
}
break;
// otherwise fall through
default:
p = findParent(e);
addProperty(p, e.name, e.value);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册