users@grizzly.java.net

Grizzly http client race condition

From: testn <test1_at_doramail.com>
Date: Tue, 26 May 2015 10:57:09 -0700 (MST)

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.