users@grizzly.java.net

Re: Grizzly http client race condition

From: Oleksiy Stashok <oleksiy.stashok_at_oracle.com>
Date: Thu, 28 May 2015 11:42:55 +0200

Hi,

it's expected behavior, Grizzly Buffer, which is backed by a byte[]
could be written asynchronously, that's why the payload could be broken
(just saw your analysis and it's 100% correct).
Why don't you use simple requestBuilder.setFile(File)?

WBR,
Alexey.

On 26.05.15 19:57, testn wrote:
> 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.