s3proxy
s3proxy copied to clipboard
intermittent getBlob exception
I haven't narrowed down what triggers this yet, but goofys CI tests trigger this (unclear which test):
java.util.NoSuchElementException: null
at java.util.ArrayDeque.removeFirst(ArrayDeque.java:285)
at com.google.common.io.Closer.close(Closer.java:212)
at org.jclouds.util.Closeables2.closeQuietly(Closeables2.java:40)
at org.jclouds.io.payloads.ByteSourcePayload.release(ByteSourcePayload.java:52)
at org.jclouds.http.internal.PayloadEnclosingImpl.setPayload(PayloadEnclosingImpl.java:56)
at org.jclouds.blobstore.domain.internal.BlobImpl.setPayload(BlobImpl.java:114)
at org.jclouds.http.internal.PayloadEnclosingImpl.setPayload(PayloadEnclosingImpl.java:97)
at org.jclouds.blobstore.config.LocalBlobStore.getBlob(LocalBlobStore.java:723)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.google.inject.internal.DelegatingInvocationHandler.invoke(DelegatingInvocationHandler.java:37)
at com.sun.proxy.$Proxy40.getBlob(Unknown Source)
at org.gaul.s3proxy.S3ProxyHandler.handleGetBlob(S3ProxyHandler.java:1640)
at org.gaul.s3proxy.S3ProxyHandler.doHandle(S3ProxyHandler.java:673)
at org.gaul.s3proxy.S3ProxyHandlerJetty.handle(S3ProxyHandlerJetty.java:70)
at org.gaul.shaded.org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.gaul.shaded.org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.gaul.shaded.org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at org.gaul.shaded.org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
at org.gaul.shaded.org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at org.gaul.shaded.org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.gaul.shaded.org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:748)
This is an interesting stack trace! Closer raises an exception in removeFirst below:
while (!stack.isEmpty()) {
Closeable closeable = stack.removeFirst();
Closer.register protects against null elements so one would assume that this is impossible without concurrent modification. Yet only a single thread should ever handle this...
another one with a different backtrace:
[s3proxy] W 09-12 05:33:33.879 S3Proxy-Jetty-28 o.g.s.o.e.j.server.HttpChannel:396 |::] /goofys-test-a0gh6o5fe00nh9qu/testLargeFile
java.lang.IllegalStateException: STREAM
at org.gaul.shaded.org.eclipse.jetty.server.Response.getWriter(Response.java:910)
at org.gaul.s3proxy.S3ProxyHandler.sendSimpleErrorResponse(S3ProxyHandler.java:2864)
at org.gaul.s3proxy.S3ProxyHandlerJetty.handle(S3ProxyHandlerJetty.java:146)
at org.gaul.shaded.org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.gaul.shaded.org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.gaul.shaded.org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at org.gaul.shaded.org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
at org.gaul.shaded.org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at org.gaul.shaded.org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.gaul.shaded.org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.base/java.lang.Thread.run(Thread.java:834)
This one causes the test to be stuck: https://travis-ci.org/kahing/goofys/jobs/583981057#L11071
Does this also happen in getBlob or another operation? The stack trace looks like one of the handlers called getWriter and while emitting some XML it throws an S3Exception. The handler closes the Writer and sendSimpleErrorResponse attempts to reopen it but fails. If you can reproduce this, adding a printStaceTrace will reveal the cause.
Actually the line
at org.gaul.s3proxy.S3ProxyHandlerJetty.handle(S3ProxyHandlerJetty.java:146)
reveals the cause, a TimeoutException, likely from the client. In this case we need more robust handling, first figure out if the stream has be opened and conditionally call into sendSimpleErrorResponse.
It looks like sendSimpleErrorResponse should check ServletResponse.isCommitted:
https://docs.oracle.com/javaee/6/api/javax/servlet/ServletResponse.html#isCommitted()
Similar symptom seen in s3fs CI:
[s3proxy] W 07-09 12:54:28.324 S3Proxy-Jetty-95 o.g.s.o.e.j.server.HttpChannel:396 |::] /s3fs-integration-test/testrun-7332/big-file-s3fs.txt
java.lang.ArrayIndexOutOfBoundsException: -662657112
at java.util.ArrayDeque.addFirst(ArrayDeque.java:227)
at com.google.common.io.Closer.register(Closer.java:126)
at org.jclouds.io.payloads.ByteSourcePayload.openStream(ByteSourcePayload.java:39)
at org.jclouds.blobstore.config.LocalBlobStore.copyBlob(LocalBlobStore.java:759)
at org.jclouds.blobstore.config.LocalBlobStore.getBlob(LocalBlobStore.java:677)
at sun.reflect.GeneratedMethodAccessor17.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.google.inject.internal.DelegatingInvocationHandler.invoke(DelegatingInvocationHandler.java:37)
at com.sun.proxy.$Proxy40.getBlob(Unknown Source)
at org.gaul.s3proxy.S3ProxyHandler.handleGetBlob(S3ProxyHandler.java:1712)
at org.gaul.s3proxy.S3ProxyHandler.doHandle(S3ProxyHandler.java:684)
at org.gaul.s3proxy.S3ProxyHandlerJetty.handle(S3ProxyHandlerJetty.java:76)
at org.gaul.shaded.org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97)
at org.gaul.shaded.org.eclipse.jetty.server.Server.handle(Server.java:499)
at org.gaul.shaded.org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311)
at org.gaul.shaded.org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:258)
at org.gaul.shaded.org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544)
at org.gaul.shaded.org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)
at org.gaul.shaded.org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555)
at java.lang.Thread.run(Thread.java:745)
Fixed in S3Proxy 1.8.0.
I still see this with S3Proxy 2.0.0:
java.lang.ArrayIndexOutOfBoundsException: Index 12 out of bounds for length 12
at java.base/java.util.ArrayDeque.grow(ArrayDeque.java:158)
at java.base/java.util.ArrayDeque.addFirst(ArrayDeque.java:290)
at com.google.common.io.Closer.register(Closer.java:126)
at org.jclouds.io.payloads.ByteSourcePayload.openStream(ByteSourcePayload.java:39)
at org.jclouds.blobstore.config.LocalBlobStore.getBlob(LocalBlobStore.java:741)
at org.jclouds.blobstore.config.LocalBlobStore.getBlob(LocalBlobStore.java:205)
at org.jclouds.blobstore.config.LocalBlobStore.blobMetadata(LocalBlobStore.java:762)
Needs jclouds 2.6.0 upgrade.