I'm not sure whether anyone has encountered this before. Basically, there
seems to be a race condition in FeedableBodyGenerator in grizzly-http-client
1.8 that it uploaded a corrupted data. When I use this code to upload the
data, the uploaded data will not be the same as the input file. However, if
I use setBody(InputStream) method instead, it works without any problem.
This seems to be caused by a race condition in the main thread and the
grizzly IO thread. That seems that Feeder overwrites the previous chunk
before it has a chance to write that down to the socket
import com.ning.http.client.*;
import com.ning.http.client.providers.grizzly.FeedableBodyGenerator;
import com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider;
import
com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProviderConfig;
import com.ning.http.client.providers.grizzly.TransportCustomizer;
import org.glassfish.grizzly.filterchain.FilterChainBuilder;
import org.glassfish.grizzly.memory.Buffers;
import org.glassfish.grizzly.memory.MemoryManager;
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import java.io.FileInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws Exception {
GrizzlyAsyncHttpProviderConfig httpConfig = new
GrizzlyAsyncHttpProviderConfig();
httpConfig.addProperty(GrizzlyAsyncHttpProviderConfig.Property.TRANSPORT_CUSTOMIZER,
new TransportCustomizer() {
public void customize(TCPNIOTransport tcpnioTransport,
FilterChainBuilder filterChainBuilder) {
tcpnioTransport.setOptimizedForMultiplexing(true);
}
});
AsyncHttpClientConfig.Builder builder = new
AsyncHttpClientConfig.Builder();
builder.setIOThreadMultiplier(1);
// builder.setProxyServer(new ProxyServer("127.0.0.1", 8080));
builder.setAsyncHttpClientProviderConfig(httpConfig);
AsyncHttpClientConfig config = builder.build();
GrizzlyAsyncHttpProvider provider = new
GrizzlyAsyncHttpProvider(config);
AsyncHttpClient client = new AsyncHttpClient(provider);
AsyncHttpClient.BoundRequestBuilder requestBuilder =
client.preparePut("
http://192.168.8.80:8080/v1/AUTH_test/test/test");
final FeedableBodyGenerator bodyGenerator = new
FeedableBodyGenerator();
final int chunkSize = 8192;
bodyGenerator.setMaxPendingBytes(chunkSize);
final FeedableBodyGenerator.Feeder feeder = new
FeedableBodyGenerator.SimpleFeeder(bodyGenerator) {
@Override
public void flush() throws IOException {
try (FileInputStream s = new
FileInputStream("/tmp/largefile")) {
byte[] buf = new byte[chunkSize];
while (s.read(buf) > 0) {
feed(Buffers.wrap(MemoryManager.DEFAULT_MEMORY_MANAGER, buf), false);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
feed(Buffers.wrap(MemoryManager.DEFAULT_MEMORY_MANAGER,
buf, 0, 0), true);
}
}
};
bodyGenerator.setFeeder(feeder);
requestBuilder.setBody(bodyGenerator);
// FileInputStream stream = new
FileInputStream("/usr/share/oracle/parallel-0ddea0/data/1432618799130-8");
// FilterInputStream wrapper = new FilterInputStream(stream) {
// @Override
// public int read() throws IOException {
// return super.read();
// }
//
// @Override
// public int read(byte[] b) throws IOException {
// return super.read(b);
// }
//
// @Override
// public int read(byte[] b, int off, int len) throws IOException
{
// return super.read(b, off, len);
// }
// };
// requestBuilder.setBody(wrapper);
Request request = requestBuilder.build();
ListenableFuture<Response> future = client.executeRequest(request);
Response response = future.get();
System.out.println(response.getHeader("Etag"));
client.close();
}
}
--
View this message in context: http://grizzly.1045725.n5.nabble.com/Grizzly-http-client-race-condition-tp5710847.html
Sent from the Grizzly - Users mailing list archive at Nabble.com.