提交 f1f34b81 编写于 作者: K kohsuke

Merged revisions 35444-35445,35457-35458,35460-35461,35463,35465,35469 via svnmerge from

https://www.dev.java.net/svn/hudson/branches/rc

........
  r35444 | kohsuke | 2010-10-01 13:44:56 -0700 (Fri, 01 Oct 2010) | 1 line
  
  [FIXED HUDSON-7546] Fixed a possible AbstractMethodError in 1.379
........
  r35445 | kohsuke | 2010-10-01 14:04:58 -0700 (Fri, 01 Oct 2010) | 1 line
  
  [FIXED HUDSON-4229] Supported failsafe reports for the Maven2 job type.
........
  r35457 | kohsuke | 2010-10-02 10:04:35 -0700 (Sat, 02 Oct 2010) | 1 line
  
  added additional code to assist trouble-shooting.
........
  r35458 | kohsuke | 2010-10-02 10:09:44 -0700 (Sat, 02 Oct 2010) | 1 line
  
  performance optimization wrt the usage of buffer
........
  r35460 | kohsuke | 2010-10-02 10:19:25 -0700 (Sat, 02 Oct 2010) | 1 line
  
  [FIXED HUDSON-5977 HUDSON-7572] the incorrect use of WeakHashMap resulted in two instances of PipeWindows for the same OID.
........
  r35461 | kohsuke | 2010-10-02 10:30:21 -0700 (Sat, 02 Oct 2010) | 1 line
  
  debug code accidentally crept in.
........
  r35463 | kohsuke | 2010-10-02 11:21:55 -0700 (Sat, 02 Oct 2010) | 1 line
  
  [maven-release-plugin] prepare release hudson-1_379
........
  r35465 | kohsuke | 2010-10-02 11:22:14 -0700 (Sat, 02 Oct 2010) | 1 line
  
  [maven-release-plugin] prepare for next development iteration
........
  r35469 | kohsuke | 2010-10-02 12:26:53 -0700 (Sat, 02 Oct 2010) | 1 line
  
  updated changelog as a part of the release
........


git-svn-id: https://hudson.dev.java.net/svn/hudson/trunk/hudson/main@35530 71c3de6d-444a-0410-be80-ed276b4c234a
上级 2e9dd797
......@@ -4,7 +4,7 @@
<parent>
<artifactId>pom</artifactId>
<groupId>org.jvnet.hudson.main</groupId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
</parent>
<artifactId>cli</artifactId>
<name>Hudson CLI</name>
......
......@@ -28,7 +28,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -78,7 +78,7 @@ public class Tasks {
public static Task getOwnerTaskOf(SubTask t) {
try {
return t.getOwnerTask();
return _getOwnerTaskOf(t);
} catch (AbstractMethodError e) {
return (Task)t;
}
......
hudson (1.379) unstable; urgency=low
* See http://hudson.dev.java.net/changelog.html for more details.
-- Kohsuke Kawaguchi <kk@kohsuke.org> Sat, 02 Oct 2010 12:23:30 -0700
hudson (1.378) unstable; urgency=low
* See http://hudson.dev.java.net/changelog.html for more details.
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
</parent>
<artifactId>maven-plugin</artifactId>
......
......@@ -62,12 +62,14 @@ public class SurefireArchiver extends MavenReporter {
public boolean preExecute(MavenBuildProxy build, MavenProject pom, MojoInfo mojo, BuildListener listener) throws InterruptedException, IOException {
if (isSurefireTest(mojo)) {
// tell surefire:test to keep going even if there was a failure,
// so that we can record this as yellow.
// note that because of the way Maven works, just updating system property at this point is too late
XmlPlexusConfiguration c = (XmlPlexusConfiguration) mojo.configuration.getChild("testFailureIgnore");
if(c!=null && c.getValue().equals("${maven.test.failure.ignore}") && System.getProperty("maven.test.failure.ignore")==null)
c.setValue("true");
if (!mojo.is("org.apache.maven.plugins", "maven-failsafe-plugin", "integration-test")) {
// tell surefire:test to keep going even if there was a failure,
// so that we can record this as yellow.
// note that because of the way Maven works, just updating system property at this point is too late
XmlPlexusConfiguration c = (XmlPlexusConfiguration) mojo.configuration.getChild("testFailureIgnore");
if(c!=null && c.getValue().equals("${maven.test.failure.ignore}") && System.getProperty("maven.test.failure.ignore")==null)
c.setValue("true");
}
}
return true;
}
......@@ -78,7 +80,8 @@ public class SurefireArchiver extends MavenReporter {
listener.getLogger().println(Messages.SurefireArchiver_Recording());
File reportsDir;
if (mojo.is("org.apache.maven.plugins", "maven-surefire-plugin", "test")) {
if (mojo.is("org.apache.maven.plugins", "maven-surefire-plugin", "test") ||
mojo.is("org.apache.maven.plugins", "maven-failsafe-plugin", "integration-test")) {
try {
reportsDir = mojo.getConfigurationValue("reportsDirectory", File.class);
} catch (ComponentConfigurationException e) {
......@@ -156,7 +159,8 @@ public class SurefireArchiver extends MavenReporter {
private boolean isSurefireTest(MojoInfo mojo) {
if ((!mojo.is("com.sun.maven", "maven-junit-plugin", "test"))
&& (!mojo.is("org.sonatype.flexmojos", "flexmojos-maven-plugin", "test-run"))
&& (!mojo.is("org.apache.maven.plugins", "maven-surefire-plugin", "test")))
&& (!mojo.is("org.apache.maven.plugins", "maven-surefire-plugin", "test"))
&& (!mojo.is("org.apache.maven.plugins", "maven-failsafe-plugin", "integration-test")))
return false;
try {
......
......@@ -33,7 +33,7 @@ THE SOFTWARE.
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Hudson main module</name>
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
......@@ -24,6 +24,7 @@
package hudson.remoting;
import hudson.remoting.ExportTable.ExportList;
import hudson.remoting.PipeWindow.Key;
import hudson.remoting.PipeWindow.Real;
import hudson.remoting.forward.ListeningPort;
import hudson.remoting.forward.ForwarderFactory;
......@@ -36,8 +37,11 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Vector;
......@@ -45,7 +49,10 @@ import java.util.WeakHashMap;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
import java.net.URL;
......@@ -143,14 +150,23 @@ public class Channel implements VirtualChannel, IChannel {
private final ExportTable<Object> exportedObjects = new ExportTable<Object>();
/**
* {@link PipeWindow}s keyed by their OIDs. Weak map, to simplify the GC of the instances.
* Strong references are kept from {@link ProxyOutputStream}.
* {@link PipeWindow}s keyed by their OIDs (of the OutputStream exported by the other side.)
*
* I haven't thought carefully, and it might be possible for us to lose the tracking of the window size
* in this way, but that will only result in a temporary spike in the effective window size,
* <p>
* To make the GC of {@link PipeWindow} automatic, the use of weak references here are tricky.
* A strong reference to {@link PipeWindow} is kept from {@link ProxyOutputStream}, and
* this is the only strong reference. Thus while {@link ProxyOutputStream} is alive,
* it keeps {@link PipeWindow} referenced, which in turn keeps its {@link PipeWindow.Real#key}
* referenced, hence this map can be looked up by the OID. When the {@link ProxyOutputStream}
* will be gone, the key is no longer strongly referenced, so it'll get cleaned up.
*
* <p>
* In some race condition situation, it might be possible for us to lose the tracking of the collect
* window size. But as long as we can be sure that there's only one {@link PipeWindow} instance
* per OID, it will only result in a temporary spike in the effective window size,
* and therefore should be OK.
*/
private final WeakHashMap<Integer,PipeWindow> pipeWindows = new WeakHashMap<Integer, PipeWindow>();
private final WeakHashMap<PipeWindow.Key, WeakReference<PipeWindow>> pipeWindows = new WeakHashMap<PipeWindow.Key, WeakReference<PipeWindow>>();
/**
* Registered listeners.
......@@ -588,10 +604,17 @@ public class Channel implements VirtualChannel, IChannel {
return PipeWindow.FAKE;
synchronized (pipeWindows) {
PipeWindow v = pipeWindows.get(oid);
if (v==null)
pipeWindows.put(oid,v = new Real(PIPE_WINDOW_SIZE));
return v;
Key k = new Key(oid);
WeakReference<PipeWindow> v = pipeWindows.get(k);
if (v!=null) {
PipeWindow w = v.get();
if (w!=null)
return w;
}
Real w = new Real(k, PIPE_WINDOW_SIZE);
pipeWindows.put(k,new WeakReference<PipeWindow>(w));
return w;
}
}
......
......@@ -40,6 +40,12 @@ public class FastPipedOutputStream extends OutputStream {
WeakReference<FastPipedInputStream> sink;
/**
* Keeps track of the total # of bytes written via this output stream.
* Helps with debugging, and serves no other purpose.
*/
private long written=0;
/**
* Creates an unconnected PipedOutputStream.
*/
......@@ -178,6 +184,7 @@ public class FastPipedOutputStream extends OutputStream {
off += amount;
len -= amount;
written += amount;
s.buffer.notifyAll();
}
......
......@@ -24,6 +24,10 @@
package hudson.remoting;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import static java.util.logging.Level.*;
/**
* Keeps track of the number of bytes that the sender can send without overwhelming the receiver of the pipe.
......@@ -74,16 +78,48 @@ abstract class PipeWindow {
}
};
static final class Key {
public final int oid;
Key(int oid) {
this.oid = oid;
}
@Override
public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) return false;
return oid == ((Key) o).oid;
}
@Override
public int hashCode() {
return oid;
}
}
static class Real extends PipeWindow {
private int available;
private long written;
private long acked;
private final int oid;
/**
* The only strong reference to the key, which in turn
* keeps this object accessible in {@link Channel#pipeWindows}.
*/
private final Key key;
Real(int initialSize) {
Real(Key key, int initialSize) {
this.key = key;
this.oid = key.oid;
this.available = initialSize;
}
public synchronized void increase(int delta) {
if (LOGGER.isLoggable(INFO))
LOGGER.info(String.format("increase(%d,%d)->%d",oid,delta,delta+available));
available += delta;
acked += delta;
notifyAll();
}
......@@ -93,17 +129,38 @@ abstract class PipeWindow {
/**
* Blocks until some space becomes available.
*
* <p>
* If the window size is empty, induce some delay outside the synchronized block,
* to avoid fragmenting the window size. That is, if a bunch of small ACKs come in a sequence,
* bundle them up into a bigger size before making a call.
*/
public synchronized int get() throws InterruptedException {
while (available==0)
wait();
return available;
public int get() throws InterruptedException {
synchronized (this) {
if (available>0)
return available;
while (available==0) {
wait();
}
}
Thread.sleep(10);
synchronized (this) {
return available;
}
}
public synchronized void decrease(int delta) {
if (LOGGER.isLoggable(INFO))
LOGGER.info(String.format("decrease(%d,%d)->%d",oid,delta,available-delta));
available -= delta;
written+= delta;
if (available<0)
throw new AssertionError();
}
}
private static final Logger LOGGER = Logger.getLogger(PipeWindow.class.getName());
}
......@@ -87,7 +87,7 @@ final class ProxyOutputStream extends OutputStream {
if(tmp!=null) {
byte[] b = tmp.toByteArray();
tmp = null;
_write(b);
_write(b,0,b.length);
}
if(closed) // already marked closed?
doClose();
......@@ -103,50 +103,31 @@ final class ProxyOutputStream extends OutputStream {
_write(b, off, len);
}
private void _write(byte[] b, int off, int len) throws IOException {
if(off==0 && len==b.length)
_write(b);
else {
byte[] buf = new byte[len];
System.arraycopy(b,off,buf,0,len);
_write(buf);
}
}
public synchronized void write(byte b[]) throws IOException {
if(closed)
throw new IOException("stream is already closed");
_write(b);
}
/**
* {@link #write(byte[])} without the close check.
*/
private void _write(byte[] b) throws IOException {
private void _write(byte[] b, int off, int len) throws IOException {
if(channel==null) {
if(tmp==null)
tmp = new ByteArrayOutputStream();
tmp.write(b);
tmp.write(b,off,len);
} else {
int sendable;
try {
sendable = Math.min(window.get(),b.length);
} catch (InterruptedException e) {
throw (IOException)new InterruptedIOException().initCause(e);
}
while (len>0) {
int sendable;
try {
sendable = Math.min(window.get(),len);
} catch (InterruptedException e) {
throw (IOException)new InterruptedIOException().initCause(e);
}
if (sendable==b.length) {
channel.send(new Chunk(oid,b,off,sendable));
window.decrease(sendable);
channel.send(new Chunk(oid,b));
} else {
// fill the sender window size now, and send the rest in a separate chunk
_write(b,0,sendable);
_write(b,sendable,b.length-sendable);
off+=sendable;
len-=sendable;
}
}
}
public void flush() throws IOException {
if(channel!=null)
channel.send(new Flush(oid));
......@@ -182,13 +163,18 @@ final class ProxyOutputStream extends OutputStream {
private final int oid;
private final byte[] buf;
public Chunk(int oid, byte[] buf) {
public Chunk(int oid, byte[] buf, int start, int len) {
// to improve the performance when a channel is used purely as a pipe,
// don't record the stack trace. On FilePath.writeToTar case, the stack trace and the OOS header
// takes up about 1.5K.
super(false);
this.oid = oid;
this.buf = buf;
if (start==0 && len==buf.length)
this.buf = buf;
else {
this.buf = new byte[len];
System.arraycopy(buf,start,this.buf,0,len);
}
}
protected void execute(final Channel channel) {
......@@ -326,12 +312,14 @@ final class ProxyOutputStream extends OutputStream {
private final int size;
private Ack(int oid, int size) {
super(false); // performance optimization
this.oid = oid;
this.size = size;
}
protected void execute(Channel channel) {
channel.getPipeWindow(oid).increase(size);
PipeWindow w = channel.getPipeWindow(oid);
w.increase(size);
}
public String toString() {
......
......@@ -25,6 +25,7 @@ package hudson.remoting;
import hudson.remoting.ChannelRunner.InProcessCompatibilityMode;
import junit.framework.Test;
import org.apache.commons.io.output.NullOutputStream;
import java.io.DataInputStream;
import java.io.OutputStream;
......@@ -195,6 +196,22 @@ public class PipeTest extends RmiTestBase {
in.close();
}
public void _testSendBigStuff() throws Exception {
OutputStream f = channel.call(new DevNullSink());
for (int i=0; i<1024*1024; i++)
f.write(new byte[8000]);
f.close();
}
private static class DevNullSink implements Callable<OutputStream, IOException> {
public OutputStream call() throws IOException {
return new RemoteOutputStream(new NullOutputStream());
}
}
public static Test suite() throws Exception {
return buildSuite(PipeTest.class);
}
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<artifactId>pom</artifactId>
<groupId>org.jvnet.hudson.main</groupId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.jvnet.hudson.main</groupId>
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
</parent>
<artifactId>ui-samples-plugin</artifactId>
......
......@@ -27,7 +27,7 @@ THE SOFTWARE.
<parent>
<groupId>org.jvnet.hudson.main</groupId>
<artifactId>pom</artifactId>
<version>1.379-SNAPSHOT</version>
<version>1.380-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册