users@grizzly.java.net

Re: Upload a large file without oom with Grizzly

From: Ryan Lubke <ryan.lubke_at_oracle.com>
Date: Thu, 12 Sep 2013 10:08:01 -0700

Sébastien Lorber wrote:
>
>
>
> I noticed something strange.
> On the FileInputStream I have, I've added a log on the close() of the
> stream which is called once the whole file has been read to be sent to
> the feeder.
>
> 1) If I perform a request (ie my session init request in the previous
> discussions) before doing my multipart upload, the thread that does
> execute the feeding is the thread that fires the request, and not a
> Grizzly worker.
> [Thread-30] INFO Will close file stream
> java.io.FileInputStream_at_27fe4315 after having read 1440304 bytes
>
>
> 2) If I don't do any request before firing the multipart upload, the
> thread that does the feeding is a Grizzly threadpool worker thread:
> [Grizzly(22)] INFO Will close file stream
> java.io.FileInputStream_at_59ac4002 after having read 1440304 bytes
>
>
> Is this normal? I would expect a worker thread to always be used, and
> the main applicative thread that performs the request to never be
> blocking. (but it's not such an issue for me, we don't have a reactive
> non-blocking app anyway)
It's currently expected behavior. Will need to re-evaluate this based
on the new semantics of the FeedableBodyGenerator.
>
>
> On the 1st case, here's the stacktrace when the feed method is called:
>
> *at
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.initializeAsynchronousTransfer(FeedableBodyGenerator.java:178)*
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$BodyGeneratorBodyHandler.doHandle(GrizzlyAsyncHttpProvider.java:2210)
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider.sendRequest(GrizzlyAsyncHttpProvider.java:564)
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$AsyncHttpClientFilter.sendAsGrizzlyRequest(GrizzlyAsyncHttpProvider.java:913)
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$AsyncHttpClientFilter.handleWrite(GrizzlyAsyncHttpProvider.java:795)
> at
> org.glassfish.grizzly.filterchain.ExecutorResolver$8.execute(ExecutorResolver.java:111)
> at
> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
> at
> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
> at
> org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
> at
> org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
> at
> org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
> at
> org.glassfish.grizzly.filterchain.DefaultFilterChain.write(DefaultFilterChain.java:437)
> at org.glassfish.grizzly.nio.NIOConnection.write(NIOConnection.java:387)
> at org.glassfish.grizzly.nio.NIOConnection.write(NIOConnection.java:361)
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider.execute(GrizzlyAsyncHttpProvider.java:307)
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$1.completed(GrizzlyAsyncHttpProvider.java:224)
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$1.completed(GrizzlyAsyncHttpProvider.java:210)
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$ConnectionManager.doAsyncTrackedConnection(GrizzlyAsyncHttpProvider.java:2289)
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider.execute(GrizzlyAsyncHttpProvider.java:244)
> *at
> com.ning.http.client.AsyncHttpClient.executeRequest(AsyncHttpClient.java:534)*
>
> So it seems this happen when the handshake has already been done when
> *initializeAsynchronousTransfer* is called, so that we do not go
> through the HandshakeListener
>
>
> Notice that this case seems to also happen in a few threads on the 2nd
> case, but most of the threads are Grizzly workers.
>
>
>
>
>
>
>
>
> 2013/9/12 Sébastien Lorber <lorber.sebastien_at_gmail.com
> <mailto:lorber.sebastien_at_gmail.com>>
>
>
>
> Hi.
>
>
> Thanks, it seems to work.
>
> I would suggest to throw IOException on the flush method since the
> feed method is supposed to be called here
>
>
> My implementation of flush is:
>
> @Override
> public void flush() {
> Part[] partsArray = parts.toArray(new Part[parts.size()]);
> try ( OutputStream outputStream =
> createFeedingOutputStream() ) {
> Part.sendParts(outputStream,partsArray,multipartBoundary);
> } catch (Exception e) {
> throw new IllegalStateException("Unable to feed the
> FeedableBodyGenerator",e);
> }
> }
>
> Is this correct? The OutputStream redirects the bytes written to
> the feed(Buffer) method
>
>
>
>
>
>
> There seems to be some concurrency issue. Because the upload of 1
> file seems fine, but when using multiple threads, I often get the
> following stack:
> Caused by: java.io.IOException: Stream Closed
> at java.io.FileInputStream.readBytes(Native Method)
> at java.io.FileInputStream.read(FileInputStream.java:242)
> at
> com.google.common.io.CountingInputStream.read(CountingInputStream.java:62)
> at java.io.FilterInputStream.read(FilterInputStream.java:133)
> at java.io.FilterInputStream.read(FilterInputStream.java:107)
> at com.ning.http.multipart.FilePart.sendData(FilePart.java:178)
> at com.ning.http.multipart.Part.send(Part.java:331)
> at com.ning.http.multipart.Part.sendParts(Part.java:397)
>
>
> This is because the flush() method is called multiple times for
> the same request on some cases.
> I guess this is not supposed to happen.
> What I understand is that the flush() method is supposed to be
> called only once.
>
>
> Using debug logging breakpoints I get the following:
>
> myapp--api-test 12/09/2013-12:20:46.042 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 0 started
> myapp--api-test 12/09/2013-12:20:46.042 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 1 started
> myapp--api-test 12/09/2013-12:20:46.043 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 2 started
> myapp--api-test 12/09/2013-12:20:46.043 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 3 started
> myapp--api-test 12/09/2013-12:20:46.043 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 4 started
> myapp--api-test 12/09/2013-12:20:46.044 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 5 started
> myapp--api-test 12/09/2013-12:20:46.044 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 6 started
> myapp--api-test 12/09/2013-12:20:46.044 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 7 started
> myapp--api-test 12/09/2013-12:20:46.045 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 8 started
> myapp--api-test 12/09/2013-12:20:46.045 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 9 started
> myapp--api-test 12/09/2013-12:20:46.045 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 10
> started
> myapp--api-test 12/09/2013-12:20:46.046 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 11
> started
> myapp--api-test 12/09/2013-12:20:46.047 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 12
> started
> myapp--api-test 12/09/2013-12:20:46.048 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 13
> started
> myapp--api-test 12/09/2013-12:20:46.049 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 14
> started
> myapp--api-test 12/09/2013-12:20:46.049 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 15
> started
> myapp--api-test 12/09/2013-12:20:46.050 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 16
> started
> myapp--api-test 12/09/2013-12:20:46.050 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 17
> started
> myapp--api-test 12/09/2013-12:20:46.051 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 18
> started
> myapp--api-test 12/09/2013-12:20:46.051 [] [] [main] INFO
> com.myapp.perf.DocumentUploadPerfIntegrationTest:77 - Thread 19
> started
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_417de6ff
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_6c0d6ef7
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_7799b411
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_1c940409
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_480f9510
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_3e888183
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_17840db8
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_2cbad94b
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_64c0a4ae
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_102873a6
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_3d5d9ee8
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_51557949
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_6f95de2f
> Adding handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_346d784c
> Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_7799b411
> *Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_5befaa07*
> *Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_5befaa07*
> *Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_5befaa07*
> *Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_102873a6*
> *Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_102873a6*
> Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_346d784c
> Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_64c0a4ae
> Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_674735a8
> Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_64c0a4ae
> Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_480f9510
> Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_6c0d6ef7
> Completing and removing handshake listener for
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator_at_1daf8fd8
>
>
> As you can see the same HandshakeListener seems to be called
> multiple times for the same FeedableBodyGenerator
>
> When this happens, the stack is:
>
> at
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator$1.onComplete(FeedableBodyGenerator.java:198)
> ~[async-http-client-1.7.20-SNAPSHOT.jar:na]
> at
> org.glassfish.grizzly.ssl.SSLBaseFilter.notifyHandshakeComplete(SSLBaseFilter.java:880)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.ssl.SSLFilter.notifyHandshakeComplete(SSLFilter.java:282)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.ssl.SSLBaseFilter.handleRead(SSLBaseFilter.java:275)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$SwitchingSSLFilter.handleRead(GrizzlyAsyncHttpProvider.java:2490)
> ~[async-http-client-1.7.20-SNAPSHOT.jar:na]
> at
> org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:546)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.run0(WorkerThreadIOStrategy.java:115)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.strategies.WorkerThreadIOStrategy.access$100(WorkerThreadIOStrategy.java:55)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.strategies.WorkerThreadIOStrategy$WorkerThreadRunnable.run(WorkerThreadIOStrategy.java:135)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:565)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
> at
> org.glassfish.grizzly.threadpool.AbstractThreadPool$Worker.run(AbstractThreadPool.java:545)
> ~[grizzly-framework-2.3.5.jar:2.3.5]
>
>
>
>
> So I tried with the following code:
>
> private boolean alreadyFlushed = false;
> @Override
> public synchronized void flush() {
> if ( alreadyFlushed ) {
> return;
> }
> startFeeding();
> alreadyFlushed = true;
> }
>
> It works fine when upload small files.
>
> But with larger files, I often get TimeoutException stacks for
> some of the threads:
>
> Caused by: java.util.concurrent.TimeoutException
> at
> org.glassfish.grizzly.impl.SafeFutureImpl$Sync.innerGet(SafeFutureImpl.java:367)
> at
> org.glassfish.grizzly.impl.SafeFutureImpl.get(SafeFutureImpl.java:274)
> at
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator$BaseFeeder.block(FeedableBodyGenerator.java:349)
> at
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator$BaseFeeder.blockUntilQueueFree(FeedableBodyGenerator.java:339)
> at
> com.ning.http.client.providers.grizzly.FeedableBodyGenerator$BaseFeeder.feed(FeedableBodyGenerator.java:306)
>
>
>
>
> Did I miss something?
>
>
>
>
>
>
> 2013/9/12 Ryan Lubke <ryan.lubke_at_oracle.com
> <mailto:ryan.lubke_at_oracle.com>>
>
> Committed another small change. Please make sure you're at
> the latest when you build.
>
> -rl
>
>
> Ryan Lubke wrote:
>> Okay, I've committed another set of refactorings to the
>> FeedableBodyGenerator.
>>
>> For your use case, you should extend
>> FeedableBodyGenerator.SimpleFeeder.
>>
>> Let me know if you run into issues.
>>
>>
>>
>> Sébastien Lorber wrote:
>>> Yes I think it would, so that I can feed the queue at once
>>>
>>> One thread will be locked during the feeding for nothing but
>>> it's not a real problem in my usecase.
>>>
>>>
>>> 2013/9/10 Ryan Lubke <ryan.lubke_at_oracle.com
>>> <mailto:ryan.lubke_at_oracle.com>>
>>>
>>> Would having a different listener that will be notified
>>> once async transferring has been started work better for
>>> you?
>>>
>>> Something like:
>>>
>>> onAsyncTransferInitiated() {
>>> // invoke your feed method
>>> }
>>>
>>> ?
>>>
>>>
>>>
>>> Sébastien Lorber wrote:
>>>> Unfortunatly I won't be able to use the Feeder
>>>> non-blocking stuff for now, because of how the
>>>> multipart request in handled in AHC
>>>>
>>>>
>>>> Here's my feeding method:
>>>>
>>>> public void feed() throws IOException {
>>>> Part[] partsArray = parts.toArray(new
>>>> Part[parts.size()]);
>>>> try ( OutputStream outputStream =
>>>> createFeedingOutputStream() ) {
>>>>
>>>> Part.sendParts(outputStream,partsArray,multipartBoundary);
>>>> } catch (Exception e) {
>>>> throw new IllegalStateException("Unable to feed
>>>> the FeedableBodyGenerator",e);
>>>> }
>>>> }
>>>>
>>>>
>>>> As you can see, the multipart Parts array can only be
>>>> pushed to the OutputStream, I don't have any way to
>>>> "pull" the data when the canFeed() method is triggered.
>>>>
>>>>
>>>> But I've seen that there's
>>>> a com.ning.http.multipart.MultipartBody#read that seems
>>>> to provide a memory efficient way to pull data from a
>>>> Multipart body...
>>>>
>>>> Should see what I come up with this
>>>>
>>>>
>>>> 2013/9/10 Sébastien Lorber <lorber.sebastien_at_gmail.com
>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>
>>>> It seems the Feeder is highly recommended but not
>>>> mandatory so I tried without.
>>>>
>>>> With my existing code it seems there is a
>>>> synchronization problem.
>>>>
>>>>
>>>> The feeding threads get locked to
>>>> the prematureFeed.get();
>>>>
>>>> So the Grizzly kernel threads are unable to acquire
>>>> the lock required to enter
>>>> the initializeAsynchronousTransfer method
>>>>
>>>>
>>>>
>>>> Will try with an implementation of Feeder
>>>>
>>>>
>>>>
>>>> 2013/9/10 Sébastien Lorber
>>>> <lorber.sebastien_at_gmail.com
>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>
>>>> Hmmm it seems I have a problem with one of your
>>>> maven plugins. I'll try to bypass it, but for info:
>>>>
>>>> ➜ ahc2 git:(ahc-1.7.x) mvn clean install
>>>> [WARNING]
>>>> [WARNING] Some problems were encountered while
>>>> building the effective settings
>>>> [WARNING]
>>>> 'profiles.profile[default].repositories.repository.id
>>>> <http://repositories.repository.id>' must be
>>>> unique but found duplicate repository with id
>>>> fullsix-maven-repository @
>>>> /home/slorber/.m2/settings.xml
>>>> [WARNING]
>>>> [INFO] Scanning for projects...
>>>> [INFO]
>>>> [INFO]
>>>> ------------------------------------------------------------------------
>>>> [INFO] Building Asynchronous Http Client
>>>> 1.7.20-SNAPSHOT
>>>> [INFO]
>>>> ------------------------------------------------------------------------
>>>> [INFO]
>>>> [INFO] --- maven-clean-plugin:2.4.1:clean
>>>> (default-clean) @ async-http-client ---
>>>> [INFO]
>>>> [INFO] ---
>>>> maven-enforcer-plugin:1.0-beta-1:enforce
>>>> (enforce-maven) @ async-http-client ---
>>>> [INFO]
>>>> [INFO] ---
>>>> maven-enforcer-plugin:1.0-beta-1:enforce
>>>> (enforce-versions) @ async-http-client ---
>>>> [INFO]
>>>> [INFO] ---
>>>> maven-resources-plugin:2.4.3:resources
>>>> (default-resources) @ async-http-client ---
>>>> [INFO] Using 'UTF-8' encoding to copy filtered
>>>> resources.
>>>> [INFO] skip non existing resourceDirectory
>>>> /home/slorber/Bureau/ahc2/src/main/resources
>>>> [INFO]
>>>> [INFO] --- maven-compiler-plugin:2.3.2:compile
>>>> (default-compile) @ async-http-client ---
>>>> [INFO] Compiling 158 source files to
>>>> /home/slorber/Bureau/ahc2/target/classes
>>>> [INFO]
>>>> *[INFO] ---
>>>> animal-sniffer-maven-plugin:1.6:check
>>>> (check-java-1.5-compat) @ async-http-client ---*
>>>> *[INFO] Checking unresolved references to
>>>> org.codehaus.mojo.signature:java15:1.0*
>>>> *[ERROR] Undefined reference:
>>>> java/io/IOException.<init>(Ljava/lang/Throwable;)V
>>>> in
>>>> /home/slorber/Bureau/ahc2/target/classes/com/ning/http/client/providers/grizzly/FeedableBodyGenerator.class*
>>>> [INFO]
>>>> ------------------------------------------------------------------------
>>>> [INFO] BUILD FAILURE
>>>> [INFO]
>>>> ------------------------------------------------------------------------
>>>> [INFO] Total time: 8.747s
>>>> [INFO] Finished at: Tue Sep 10 11:25:41 CEST 2013
>>>> [INFO] Final Memory: 30M/453M
>>>> [INFO]
>>>> ------------------------------------------------------------------------
>>>> *[ERROR] Failed to execute goal
>>>> org.codehaus.mojo:animal-sniffer-maven-plugin:1.6:check
>>>> (check-java-1.5-compat) on project
>>>> async-http-client: Signature errors found.
>>>> Verify them and put @IgnoreJRERequirement on
>>>> them. -> [Help 1]*
>>>> [ERROR]
>>>> [ERROR] To see the full stack trace of the
>>>> errors, re-run Maven with the -e switch.
>>>> [ERROR] Re-run Maven using the -X switch to
>>>> enable full debug logging.
>>>> [ERROR]
>>>> [ERROR] For more information about the errors
>>>> and possible solutions, please read the
>>>> following articles:
>>>> [ERROR] [Help 1]
>>>> http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException
>>>>
>>>>
>>>>
>>>> 2013/9/10 Sébastien Lorber
>>>> <lorber.sebastien_at_gmail.com
>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>
>>>> Ok thank you, I'll try to implement that
>>>> today and will give you my feedback :)
>>>>
>>>>
>>>> 2013/9/10 Ryan Lubke <ryan.lubke_at_oracle.com
>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>
>>>> Okay,
>>>>
>>>> I've committed my initial changes to
>>>> the AHC repository. Here's a summary
>>>> of the changes:
>>>>
>>>>
>>>> *Improvements to the
>>>> FeedableBodyGenerator (Grizzly's).
>>>> - Don't allow queueing of data before
>>>> initiateAsyncTransfer has been invoked.
>>>> In low memory
>>>> heaps, this could lead to an OOM if the
>>>> source is feeding too fast. The new
>>>> behavior is to
>>>> block until initiateAsyncTransfer is
>>>> called, at which time the blocked
>>>> thread may proceed with
>>>> the feed operation.
>>>> - Introduce the concept of a Feeder.
>>>> Implementations are responsible, at a
>>>> high level, for:
>>>> + letting the provider know that data
>>>> is available to be fed without blocking
>>>> + allowing the registration of a
>>>> callback that the Feeder implementation
>>>> may invoke
>>>> to signal that more data is available,
>>>> if it wasn't available at a previous
>>>> point in time.
>>>> - When using a Feeder with a secure
>>>> request, the SSL handshake will be
>>>> kicked off by the
>>>> initiateAsyncTransfer call, but feeding
>>>> of data will not occur until the
>>>> handshake is complete.
>>>> This is necessary as the SSLFilter will
>>>> queue up all writes until the handshake
>>>> is complete,
>>>> and currently, the buffer isn't tied in
>>>> with the transport flow control mechanism.
>>>> NOTE: This new SSL behavior is not
>>>> currently applied when invoking the
>>>> feed() method
>>>> outside the context of a Feeder. Still
>>>> need to address that.
>>>> - Exposed configuration of the async
>>>> write queue limit through the
>>>> FeedableBodyGenerator.
>>>> This is an improvement on using a
>>>> TransportCustomizer as any
>>>> configuration there is
>>>> transport-wide, and therefor applied to
>>>> all Connections. By exposing it here,
>>>> each feeder
>>>> may have a different byte limit.
>>>> - Improved documentation for this class*
>>>>
>>>>
>>>>
>>>> I recommend reading through the javadoc
>>>> comments in the source [1] for
>>>> FeedableBodyGenerator (comments welcome).
>>>> Additionally, I would re-work your code
>>>> to leverage the Feeder instead of
>>>> calling feed() directly.
>>>>
>>>> If you have issues implementing Feeder,
>>>> do let us know.
>>>>
>>>> If you have additional questions,
>>>> again, let us know.
>>>>
>>>> Thanks,
>>>> -rl
>>>>
>>>> [1]
>>>> https://github.com/AsyncHttpClient/async-http-client/blob/ahc-1.7.x/src/main/java/com/ning/http/client/providers/grizzly/FeedableBodyGenerator.java
>>>>
>>>>
>>>>
>>>> Ryan Lubke wrote:
>>>>>
>>>>>
>>>>> Sébastien Lorber wrote:
>>>>>> So in the end I've end up with an
>>>>>> implementation that's working for me.
>>>>>>
>>>>>>
>>>>>> I think there are 2 bugs:
>>>>>>
>>>>>> 1) The bytes can accumulate in the
>>>>>> FeedableBodyGenerator queue if the
>>>>>> initialize(ctx) method is not called
>>>>>> fast enough.
>>>>>> This can be solved by using a
>>>>>> BlockingQueue of size 1 and the put()
>>>>>> method.
>>>>>>
>>>>>> 2) Once the context is injected, the
>>>>>> FeedableBodyGenerator flushes the queue.
>>>>>> The matter is that if the connection
>>>>>> is new, not warmed up by a previous
>>>>>> request, then the SSL handshake is
>>>>>> not done yet, and it seems that the
>>>>>> bytes are accumulated in some part of
>>>>>> the SSL filter which doesn't deliver
>>>>>> them to the connection until the
>>>>>> handshake has completed,
>>>>>> so c.canWrite() continues to return true.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> I have replaced some part of the
>>>>>> FeedableBodyGenerator to test this
>>>>>> and it works pretty fine. See what I
>>>>>> have changed:
>>>>>>
>>>>>> 1)
>>>>>> private final
>>>>>> BlockingQueue<BodyPart> queue = new
>>>>>> LinkedBlockingQueue<BodyPart>(1);
>>>>>>
>>>>>>
>>>>>> 2)
>>>>>> public void feed(final Buffer
>>>>>> buffer, final boolean last) throws
>>>>>> IOException {
>>>>>> try {
>>>>>> queue.put(new
>>>>>> BodyPart(buffer, last));
>>>>>> } catch (InterruptedException
>>>>>> e) {
>>>>>> throw new RuntimeException(e);
>>>>>> }
>>>>>> queueSize.incrementAndGet();
>>>>>> if (context != null) {
>>>>>>
>>>>>> blockUntilConnectionIsReadyToWrite(context);
>>>>>> flushQueue(true);
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> private void
>>>>>> blockUntilConnectionIsReadyToWrite(FilterChainContext
>>>>>> fcc) {
>>>>>> if (
>>>>>> !connectionIsReadyToWrite(fcc) ) {
>>>>>> while (
>>>>>> !connectionIsReadyToWrite(fcc) ) {
>>>>>> try { Thread.sleep(10); }
>>>>>> catch ( Exception e ) { throw new
>>>>>> RuntimeException(e); }
>>>>>> }
>>>>>> }
>>>>>> }
>>>>>>
>>>>>> private boolean
>>>>>> connectionIsReadyToWrite(FilterChainContext
>>>>>> fcc) {
>>>>>> Connection connection =
>>>>>> fcc.getConnection();
>>>>>> SSLEngine sslEngine =
>>>>>> SSLUtils.getSSLEngine(connection);
>>>>>> return sslEngine != null &&
>>>>>> !SSLUtils.isHandshaking(sslEngine);
>>>>>> }
>>>>>>
>>>>>>
>>>>>>
>>>>>> What do you think?
>>>>>
>>>>> We had come to similar conclusions on
>>>>> this end. I'm still working through
>>>>> testing the idea I mentioned
>>>>> previously (took longer than I
>>>>> expected - sorry).
>>>>> I hope to have something for you to
>>>>> test very soon.
>>>>>
>>>>> Note that it will be taking the above
>>>>> into account as well.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> 2013/9/5 Sébastien Lorber
>>>>>> <lorber.sebastien_at_gmail.com
>>>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>>>
>>>>>>
>>>>>> I have tried to put a while (
>>>>>> context == null ) Thread.sleep
>>>>>> but it doesn't seem to work, when
>>>>>> the context gets injected, after
>>>>>> the sleeps, there's an OOM
>>>>>>
>>>>>> So I hope you'll have more
>>>>>> success with your alternative :)
>>>>>>
>>>>>>
>>>>>>
>>>>>> I have done another test,
>>>>>> remember my code that worked,
>>>>>> which previously "warmed" the
>>>>>> Thread with an useless request.
>>>>>>
>>>>>> private Runnable
>>>>>> uploadSingleDocumentRunnable =
>>>>>> new Runnable() {
>>>>>> @Override
>>>>>> public void run() {
>>>>>> try {
>>>>>> getUselessSessionCode();
>>>>>> Thread.sleep(X);
>>>>>> uploadSingleDocument();
>>>>>> } catch ( Exception e ) {
>>>>>> throw new
>>>>>> RuntimeException("file upload
>>>>>> failed",e);
>>>>>> }
>>>>>> }
>>>>>> };
>>>>>>
>>>>>> I have put a sleep of X between
>>>>>> the useless warmup request, and
>>>>>> the real upload request
>>>>>>
>>>>>>
>>>>>> What I noticed is that there is a
>>>>>> very different behavior according
>>>>>> to the value of X
>>>>>>
>>>>>>
>>>>>> Under 10 seconds, it seems the
>>>>>> stuff is still warm, I can upload
>>>>>> the documents.
>>>>>> Around 10 seconds I get a stack
>>>>>> which seems to be "connection
>>>>>> closed" or something
>>>>>> Above 10 seconds, I get OOM like
>>>>>> if the stuff wasn't warm.
>>>>>>
>>>>>>
>>>>>> The stacks I get for 10 seconds
>>>>>> looks like
>>>>>>
>>>>>> Caused by:
>>>>>> javax.net.ssl.SSLException:
>>>>>> SSLEngine is CLOSED
>>>>>> at
>>>>>> org.glassfish.grizzly.ssl.SSLConnectionContext.wrap(SSLConnectionContext.java:295)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.ssl.SSLConnectionContext.wrapAll(SSLConnectionContext.java:238)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.ssl.SSLBaseFilter.wrapAll(SSLBaseFilter.java:405)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.ssl.SSLBaseFilter.handleWrite(SSLBaseFilter.java:320)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.ssl.SSLFilter.accurateWrite(SSLFilter.java:255)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.ssl.SSLFilter.handleWrite(SSLFilter.java:143)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$SwitchingSSLFilter.handleWrite(GrizzlyAsyncHttpProvider.java:2500)
>>>>>> ~[async-http-client-1.7.20-SNAPSHOT.jar:na]
>>>>>> at
>>>>>> org.glassfish.grizzly.filterchain.ExecutorResolver$8.execute(ExecutorResolver.java:111)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.filterchain.FilterChainContext.write(FilterChainContext.java:853)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> org.glassfish.grizzly.filterchain.FilterChainContext.write(FilterChainContext.java:720)
>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>> at
>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.flushQueue(FeedableBodyGenerator.java:133)
>>>>>> ~[async-http-client-1.7.20-SNAPSHOT.jar:na]
>>>>>> at
>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.feed(FeedableBodyGenerator.java:95)
>>>>>> ~[async-http-client-1.7.20-SNAPSHOT.jar:na]
>>>>>>
>>>>>> I think I got some other
>>>>>> different stacks saying
>>>>>> Connection Closed Remotely or
>>>>>> something like that.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> So it seems that something is
>>>>>> bound to my thread, and it stays
>>>>>> bound to it for about 10 seconds,
>>>>>> do you have any idea what it
>>>>>> could be?
>>>>>> (My connection timeout setting
>>>>>> seems to have no effect on this
>>>>>> 10s threshold)
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> 2013/9/5 Ryan Lubke
>>>>>> <ryan.lubke_at_oracle.com
>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>
>>>>>> That is one solution. I'm
>>>>>> working out an alternative
>>>>>> right now. Stay tuned!
>>>>>>
>>>>>>>
>>>>>>> Anyway it's not a problem, I
>>>>>>> think the
>>>>>>> FeedableBodyGenerator.feed()
>>>>>>> method just has to block
>>>>>>> until a context has been
>>>>>>> (and ThreadCache
>>>>>>> initialized) to avoid OOM errors
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 2013/9/5 Sébastien Lorber
>>>>>>> <lorber.sebastien_at_gmail.com
>>>>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>>>>
>>>>>>>
>>>>>>> What is very strange is
>>>>>>> that I tested
>>>>>>> with/without the same
>>>>>>> sessionCode with our
>>>>>>> previous code, the one
>>>>>>> not using
>>>>>>> FeedableBodyGenerator,
>>>>>>> which has a high memory
>>>>>>> consumption.
>>>>>>> Despites the fact it had
>>>>>>> high memory consumption,
>>>>>>> it seems work fine to
>>>>>>> upload multiple
>>>>>>> documents if allocated
>>>>>>> with a large heap, and
>>>>>>> the sessionCode seems to
>>>>>>> have no effect.
>>>>>>>
>>>>>>> On the new impl using
>>>>>>> the
>>>>>>> FeedableBodyGenerator,
>>>>>>> the sessionCode sent as
>>>>>>> a multipart bodypart
>>>>>>> seems to have an effect.
>>>>>>>
>>>>>>> I have tried to feed the
>>>>>>> queue before sending the
>>>>>>> request to AHC, but this
>>>>>>> leads to this exception
>>>>>>> (with/without
>>>>>>> sessionCode switching)
>>>>>>> Caused by:
>>>>>>> java.util.concurrent.TimeoutException:
>>>>>>> Timeout exceeded
>>>>>>> at
>>>>>>> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider.timeout(GrizzlyAsyncHttpProvider.java:528)
>>>>>>> at
>>>>>>> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$3.onTimeout(GrizzlyAsyncHttpProvider.java:361)
>>>>>>> at
>>>>>>> org.glassfish.grizzly.utils.IdleTimeoutFilter$DefaultWorker.doWork(IdleTimeoutFilter.java:383)
>>>>>>> at
>>>>>>> org.glassfish.grizzly.utils.IdleTimeoutFilter$DefaultWorker.doWork(IdleTimeoutFilter.java:362)
>>>>>>> at
>>>>>>> org.glassfish.grizzly.utils.DelayedExecutor$DelayedRunnable.run(DelayedExecutor.java:158)
>>>>>>> at
>>>>>>> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
>>>>>>> at
>>>>>>> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 2013/9/5 Sébastien
>>>>>>> Lorber
>>>>>>> <lorber.sebastien_at_gmail.com
>>>>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>>>>
>>>>>>> By the way, by using
>>>>>>> a low timeout with
>>>>>>> the same
>>>>>>> sessioncode, I got
>>>>>>> the following NPE:
>>>>>>>
>>>>>>> Caused by:
>>>>>>> java.lang.NullPointerException
>>>>>>> at
>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.block(FeedableBodyGenerator.java:184)
>>>>>>> at
>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.blockUntilQueueFree(FeedableBodyGenerator.java:167)
>>>>>>> at
>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.flushQueue(FeedableBodyGenerator.java:124)
>>>>>>> at
>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.feed(FeedableBodyGenerator.java:94)
>>>>>>>
>>>>>>>
>>>>>>> GrizzlyAsyncHttpProvider.HttpTransactionContext
>>>>>>> httpCtx =
>>>>>>>
>>>>>>> getHttpTransactionContext(c);
>>>>>>>
>>>>>>> httpCtx.abort(e.getCause());
>>>>>>>
>>>>>>> I guess the httpCtx
>>>>>>> is not already
>>>>>>> available to be aborted
>>>>>>>
>>>>>>>
>>>>>>> 2013/9/5 Sébastien
>>>>>>> Lorber
>>>>>>> <lorber.sebastien_at_gmail.com
>>>>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> This is right,
>>>>>>> here's a log I
>>>>>>> have when I use
>>>>>>> the same session
>>>>>>> code, ie the
>>>>>>> remote host is
>>>>>>> blocking the
>>>>>>> data or something.
>>>>>>> This is obtained
>>>>>>> by running 5
>>>>>>> parallel uploads.
>>>>>>>
>>>>>>> *Flushing queue
>>>>>>> of size 0 with
>>>>>>> allowBlocking =
>>>>>>> false*
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> *Flushing queue
>>>>>>> of size 97 with
>>>>>>> allowBlocking =
>>>>>>> false*
>>>>>>> *Flushing queue
>>>>>>> of size 100 with
>>>>>>> allowBlocking =
>>>>>>> false*
>>>>>>> *Flushing queue
>>>>>>> of size 160 with
>>>>>>> allowBlocking =
>>>>>>> true*
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 0 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> java.lang.OutOfMemoryError:
>>>>>>> GC overhead
>>>>>>> limit exceeded
>>>>>>> Dumping heap to
>>>>>>> /ome/lorber/ureau/om
>>>>>>> ...
>>>>>>> Unable to create
>>>>>>> /ome/lorber/ureau/om:
>>>>>>> Le fichier existe
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Disconnected
>>>>>>> from the target
>>>>>>> VM, address:
>>>>>>> '127.0.0.1:49268
>>>>>>> <http://127.0.0.1:49268>',
>>>>>>> transport: 'socket'
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Otherwise, with
>>>>>>> different
>>>>>>> session codes, I
>>>>>>> get the following:
>>>>>>>
>>>>>>> *Flushing queue
>>>>>>> of size 0 with
>>>>>>> allowBlocking =
>>>>>>> false*
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> *Flushing queue
>>>>>>> of size 0 with
>>>>>>> allowBlocking =
>>>>>>> false*
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> *Flushing queue
>>>>>>> of size 0 with
>>>>>>> allowBlocking =
>>>>>>> false*
>>>>>>> *Flushing queue
>>>>>>> of size 0 with
>>>>>>> allowBlocking =
>>>>>>> false*
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> Flushing queue
>>>>>>> of size 1 with
>>>>>>> allowBlocking = true
>>>>>>> ... and this
>>>>>>> continues
>>>>>>> without OOM
>>>>>>>
>>>>>>>
>>>>>>> So, this seems
>>>>>>> to be the problem.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> I think it would
>>>>>>> be great to be
>>>>>>> able to be able
>>>>>>> to choose the
>>>>>>> queue impl
>>>>>>> behind
>>>>>>> that FeedableBodyGenerator,
>>>>>>> like I suggested
>>>>>>> in my pull request.
>>>>>>>
>>>>>>> See here:
>>>>>>> https://github.com/slorber/async-http-client/blob/79b0c3b28a61b0aa4c4b055bca8f6be11d9ed1e6/src/main/java/com/ning/http/client/providers/grizzly/FeedableBodyGenerator.java
>>>>>>>
>>>>>>> Using a
>>>>>>> LinkedBlockingQueue
>>>>>>> seems to be a
>>>>>>> nice idea in
>>>>>>> this context,
>>>>>>> and in my case I
>>>>>>> would probably
>>>>>>> use a queue of
>>>>>>> size 1
>>>>>>>
>>>>>>>
>>>>>>> This would
>>>>>>> handle the
>>>>>>> blocking of the
>>>>>>> feed method,
>>>>>>> without having
>>>>>>> to use this:
>>>>>>> if
>>>>>>> (context != null) {
>>>>>>>
>>>>>>> flushQueue(true);
>>>>>>> }
>>>>>>>
>>>>>>>
>>>>>>> Or perhaps the
>>>>>>> feed() method
>>>>>>> have to wait
>>>>>>> until a context
>>>>>>> is set in the
>>>>>>> BodyGenerator ?
>>>>>>>
>>>>>>>
>>>>>>> I think it would
>>>>>>> be more clear if
>>>>>>> the initializeAsynchronousTransfer
>>>>>>> simply didn't
>>>>>>> flush the queue
>>>>>>> but just setup
>>>>>>> the context.
>>>>>>> Then the feed
>>>>>>> method would
>>>>>>> block until
>>>>>>> there's a
>>>>>>> context set, and
>>>>>>> then flush the
>>>>>>> queue with
>>>>>>> blocking behavior.
>>>>>>>
>>>>>>> This is probably
>>>>>>> the next step,
>>>>>>> but as we are
>>>>>>> using AHC for
>>>>>>> async, it would
>>>>>>> probably be
>>>>>>> great if that
>>>>>>> blocking feed()
>>>>>>> method was
>>>>>>> called in a
>>>>>>> worker thread
>>>>>>> instead of our
>>>>>>> main thread.
>>>>>>> I won't use this
>>>>>>> but someone who
>>>>>>> really wants a
>>>>>>> non-blocking
>>>>>>> impl of
>>>>>>> performant
>>>>>>> multipart
>>>>>>> fileupload would
>>>>>>> probably need
>>>>>>> this, or will
>>>>>>> use an
>>>>>>> ExecutorService
>>>>>>> for the feeding
>>>>>>> operations as a
>>>>>>> workaround.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Thanks again for
>>>>>>> your reactivity
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> 2013/9/4 Ryan
>>>>>>> Lubke
>>>>>>> <ryan.lubke_at_oracle.com
>>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> Sébastien
>>>>>>> Lorber wrote:
>>>>>>>> I've
>>>>>>>> integrated
>>>>>>>> this change
>>>>>>>> and it
>>>>>>>> works fine
>>>>>>>> except a
>>>>>>>> little detail.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> I'm
>>>>>>>> uploading
>>>>>>>> files to a
>>>>>>>> third party
>>>>>>>> API (a bit
>>>>>>>> like S3).
>>>>>>>> This API
>>>>>>>> requires a
>>>>>>>> "sessionCode"
>>>>>>>> in each
>>>>>>>> request. So
>>>>>>>> there is a
>>>>>>>> multipart
>>>>>>>> StringPart
>>>>>>>> with that
>>>>>>>> SessionCode.
>>>>>>>>
>>>>>>>> We used to
>>>>>>>> have a
>>>>>>>> cache which
>>>>>>>> holds the
>>>>>>>> sessionCode
>>>>>>>> 30min per
>>>>>>>> user so
>>>>>>>> that we do
>>>>>>>> not need to
>>>>>>>> init a new
>>>>>>>> session
>>>>>>>> each time.
>>>>>>>>
>>>>>>>> I had
>>>>>>>> troubles in
>>>>>>>> this very
>>>>>>>> specific
>>>>>>>> case: when
>>>>>>>> I upload 5
>>>>>>>> docs with
>>>>>>>> the same
>>>>>>>> session code.
>>>>>>>> When I
>>>>>>>> remove the
>>>>>>>> cache and
>>>>>>>> use 5
>>>>>>>> different
>>>>>>>> session
>>>>>>>> codes, it
>>>>>>>> works fine.
>>>>>>>>
>>>>>>>> I guess the
>>>>>>>> remote
>>>>>>>> service is
>>>>>>>> blocking
>>>>>>>> concurrent
>>>>>>>> uploads
>>>>>>>> with the
>>>>>>>> same
>>>>>>>> session
>>>>>>>> code. I
>>>>>>>> don't know
>>>>>>>> at all.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Where I
>>>>>>>> want to go
>>>>>>>> is that I
>>>>>>>> wouldn't
>>>>>>>> have
>>>>>>>> expected
>>>>>>>> Grizzly to OOM
>>>>>>>>
>>>>>>>>
>>>>>>>> Avertissement:
>>>>>>>> Exception
>>>>>>>> during
>>>>>>>> FilterChain
>>>>>>>> execution
>>>>>>>> java.lang.OutOfMemoryError:
>>>>>>>> Java heap space
>>>>>>>> at
>>>>>>>> java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:57)
>>>>>>>> at
>>>>>>>> java.nio.ByteBuffer.allocate(ByteBuffer.java:331)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLUtils.allocateOutputBuffer(SSLUtils.java:342)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLBaseFilter$2.grow(SSLBaseFilter.java:117)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLConnectionContext.ensureBufferSize(SSLConnectionContext.java:392)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLConnectionContext.wrap(SSLConnectionContext.java:272)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLConnectionContext.wrapAll(SSLConnectionContext.java:238)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLBaseFilter.wrapAll(SSLBaseFilter.java:405)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLBaseFilter.handleWrite(SSLBaseFilter.java:320)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLFilter.accurateWrite(SSLFilter.java:263)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLFilter.handleWrite(SSLFilter.java:143)
>>>>>>>> at
>>>>>>>> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$SwitchingSSLFilter.handleWrite(GrizzlyAsyncHttpProvider.java:2500)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.ExecutorResolver$8.execute(ExecutorResolver.java:111)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.FilterChainContext$1.run(FilterChainContext.java:196)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.FilterChainContext.resume(FilterChainContext.java:220)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLFilter$SSLHandshakeContext.completed(SSLFilter.java:383)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLFilter.notifyHandshakeComplete(SSLFilter.java:278)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ssl.SSLBaseFilter.handleRead(SSLBaseFilter.java:275)
>>>>>>>> at
>>>>>>>> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$SwitchingSSLFilter.handleRead(GrizzlyAsyncHttpProvider.java:2490)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.ExecutorResolver$9.execute(ExecutorResolver.java:119)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:546)
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.strategies.AbstractIOStrategy.fireIOEvent(AbstractIOStrategy.java:113)
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Caused by:
>>>>>>>> java.util.concurrent.TimeoutException:
>>>>>>>> null
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.impl.SafeFutureImpl$Sync.innerGet(SafeFutureImpl.java:367)
>>>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>>>> at
>>>>>>>> org.glassfish.grizzly.impl.SafeFutureImpl.get(SafeFutureImpl.java:274)
>>>>>>>> ~[grizzly-framework-2.3.5.jar:2.3.5]
>>>>>>>> at
>>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.block(FeedableBodyGenerator.java:177)
>>>>>>>> ~[async-http-client-1.7.20-204092c.jar:na]
>>>>>>>> at
>>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.blockUntilQueueFree(FeedableBodyGenerator.java:167)
>>>>>>>> ~[async-http-client-1.7.20-204092c.jar:na]
>>>>>>>> at
>>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.flushQueue(FeedableBodyGenerator.java:124)
>>>>>>>> ~[async-http-client-1.7.20-204092c.jar:na]
>>>>>>>> at
>>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.feed(FeedableBodyGenerator.java:94)
>>>>>>>> ~[async-http-client-1.7.20-204092c.jar:na]
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> multipart.body.generator.feeder.buffer=100000
>>>>>>>> -> size of
>>>>>>>> each Buffer
>>>>>>>> sent to the
>>>>>>>> FeedableBodyGenerator
>>>>>>>> transport.max.pending.bytes=1000000
>>>>>>>> (I tried
>>>>>>>> other
>>>>>>>> settings,
>>>>>>>> including
>>>>>>>> AUTO_SIZE)
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Do you have
>>>>>>>> any idea
>>>>>>>> why is
>>>>>>>> there an
>>>>>>>> OOM with
>>>>>>>> these settings?
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Perhaps it
>>>>>>>> is because
>>>>>>>> the feed()
>>>>>>>> method of
>>>>>>>> FeedableBodyGenerator
>>>>>>>> doesn't
>>>>>>>> block until
>>>>>>>> the context
>>>>>>>> is
>>>>>>>> initialized.
>>>>>>>> I guess
>>>>>>>> the initializeAsynchronousTransfer
>>>>>>>> is called
>>>>>>>> only once
>>>>>>>> the
>>>>>>>> connection
>>>>>>>> is
>>>>>>>> established, and
>>>>>>>> perhaps a
>>>>>>>> lot of
>>>>>>>> Buffer are
>>>>>>>> added to
>>>>>>>> the queue...
>>>>>>> Yes, it's
>>>>>>> invoked once
>>>>>>> the request
>>>>>>> has been
>>>>>>> dispatched,
>>>>>>> so if the
>>>>>>> generator is
>>>>>>> fed a lot
>>>>>>> before the
>>>>>>> request, I
>>>>>>> could see
>>>>>>> this happening.
>>>>>>> I'll see
>>>>>>> what I can
>>>>>>> do to
>>>>>>> alleviate
>>>>>>> that case.
>>>>>>>
>>>>>>>>
>>>>>>>> But I'm not
>>>>>>>> sure at all
>>>>>>>> because the
>>>>>>>> session
>>>>>>>> code is
>>>>>>>> transmitted
>>>>>>>> as a
>>>>>>>> BodyPart
>>>>>>>> and I get
>>>>>>>> the same
>>>>>>>> problem if
>>>>>>>> i put it as
>>>>>>>> the first
>>>>>>>> or last
>>>>>>>> multipart.
>>>>>>>>
>>>>>>>> It's not a
>>>>>>>> big deal,
>>>>>>>> perhaps I
>>>>>>>> should
>>>>>>>> always use
>>>>>>>> a different
>>>>>>>> session
>>>>>>>> code for
>>>>>>>> concurrent
>>>>>>>> operations
>>>>>>>> but I'd
>>>>>>>> like to be
>>>>>>>> sure that
>>>>>>>> we won't
>>>>>>>> have this
>>>>>>>> issue in
>>>>>>>> production...
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> 2013/9/3
>>>>>>>> Ryan Lubke
>>>>>>>> <ryan.lubke_at_oracle.com
>>>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>>>
>>>>>>>> Good
>>>>>>>> catch.
>>>>>>>> Fixed.
>>>>>>>>
>>>>>>>>
>>>>>>>> Sébastien
>>>>>>>> Lorber
>>>>>>>> wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Hello,
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> There's a
>>>>>>>>> little
>>>>>>>>> mistake in
>>>>>>>>> the
>>>>>>>>> grizzly ahc
>>>>>>>>> provider
>>>>>>>>> relative
>>>>>>>>> to the
>>>>>>>>> write
>>>>>>>>> queue
>>>>>>>>> size.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> https://github.com/AsyncHttpClient/async-http-client/blob/b5d97efe9fe14113ea92fb1f7db192a2d090fad7/src/main/java/com/ning/http/client/providers/grizzly/GrizzlyAsyncHttpProvider.java#L419
>>>>>>>>>
>>>>>>>>> As you
>>>>>>>>> can
>>>>>>>>> see,
>>>>>>>>> the
>>>>>>>>> TransportCustomizer
>>>>>>>>> is
>>>>>>>>> called, and
>>>>>>>>> then
>>>>>>>>> the
>>>>>>>>> write
>>>>>>>>> queue
>>>>>>>>> size
>>>>>>>>> (among
>>>>>>>>> other
>>>>>>>>> things) is
>>>>>>>>> set to
>>>>>>>>> AUTO_SIZE
>>>>>>>>> (instead
>>>>>>>>> of
>>>>>>>>> previously
>>>>>>>>> UNLIMITED)
>>>>>>>>>
>>>>>>>>> clientTransport.getAsyncQueueIO().getWriter()
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> .setMaxPendingBytesPerConnection(AsyncQueueWriter.AUTO_SIZE);
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> I
>>>>>>>>> think
>>>>>>>>> the
>>>>>>>>> default settings
>>>>>>>>> like
>>>>>>>>> this
>>>>>>>>> AUTO_SIZE
>>>>>>>>> attribute
>>>>>>>>> should
>>>>>>>>> be set
>>>>>>>>> before
>>>>>>>>> the
>>>>>>>>> customization
>>>>>>>>> of the
>>>>>>>>> transport,
>>>>>>>>> or
>>>>>>>>> they
>>>>>>>>> would
>>>>>>>>> override
>>>>>>>>> the
>>>>>>>>> value
>>>>>>>>> we
>>>>>>>>> customized.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> This
>>>>>>>>> is
>>>>>>>>> actually
>>>>>>>>> my
>>>>>>>>> case,
>>>>>>>>> since
>>>>>>>>> I
>>>>>>>>> can't
>>>>>>>>> reproduce
>>>>>>>>> my
>>>>>>>>> "bug"
>>>>>>>>> which
>>>>>>>>> is
>>>>>>>>> "high
>>>>>>>>> memory
>>>>>>>>> consumption",
>>>>>>>>> even
>>>>>>>>> when
>>>>>>>>> using
>>>>>>>>> -1 /
>>>>>>>>> UNLIMITED
>>>>>>>>> in the
>>>>>>>>> TransportCustomizer.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> This
>>>>>>>>> could
>>>>>>>>> work
>>>>>>>>> fine
>>>>>>>>> for me
>>>>>>>>> with
>>>>>>>>> AUTO_SIZE,
>>>>>>>>> but
>>>>>>>>> I'd
>>>>>>>>> rather
>>>>>>>>> be
>>>>>>>>> able
>>>>>>>>> to
>>>>>>>>> tune
>>>>>>>>> this
>>>>>>>>> parameter
>>>>>>>>> during
>>>>>>>>> load
>>>>>>>>> tests
>>>>>>>>> to see
>>>>>>>>> the
>>>>>>>>> effect.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 2013/8/31
>>>>>>>>> Sebastien
>>>>>>>>> Lorber
>>>>>>>>> <lorber.sebastien_at_gmail.com
>>>>>>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>>>>>>
>>>>>>>>> Thanks
>>>>>>>>> i
>>>>>>>>> will
>>>>>>>>> ckeck
>>>>>>>>> that
>>>>>>>>> on
>>>>>>>>> monday.
>>>>>>>>> I
>>>>>>>>> can now
>>>>>>>>> upload
>>>>>>>>> a
>>>>>>>>> 500m
>>>>>>>>> file
>>>>>>>>> with
>>>>>>>>> 40m heap
>>>>>>>>> size
>>>>>>>>> ;)
>>>>>>>>>
>>>>>>>>> Envoyé
>>>>>>>>> de
>>>>>>>>> mon iPhone
>>>>>>>>>
>>>>>>>>> Le
>>>>>>>>> 30
>>>>>>>>> août
>>>>>>>>> 2013
>>>>>>>>> à
>>>>>>>>> 20:49,
>>>>>>>>> Ryan
>>>>>>>>> Lubke
>>>>>>>>> <ryan.lubke_at_oracle.com
>>>>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>>>> a
>>>>>>>>> écrit :
>>>>>>>>>
>>>>>>>>>> I'm
>>>>>>>>>> going
>>>>>>>>>> to be
>>>>>>>>>> updating
>>>>>>>>>> the
>>>>>>>>>> Grizzly
>>>>>>>>>> provider
>>>>>>>>>> such
>>>>>>>>>> that
>>>>>>>>>> AUTO_SIZE
>>>>>>>>>> (not
>>>>>>>>>> AUTO_TUNE)
>>>>>>>>>> is the
>>>>>>>>>> default,
>>>>>>>>>> so you
>>>>>>>>>> can
>>>>>>>>>> avoid
>>>>>>>>>> the
>>>>>>>>>> use
>>>>>>>>>> of the
>>>>>>>>>> TransportCustomizer.
>>>>>>>>>>
>>>>>>>>>> Ryan
>>>>>>>>>> Lubke
>>>>>>>>>> wrote:
>>>>>>>>>>
>>>>>>>>>>> Regarding
>>>>>>>>>>> your
>>>>>>>>>>> tuning
>>>>>>>>>>> question,
>>>>>>>>>>> I would
>>>>>>>>>>> probably
>>>>>>>>>>> set
>>>>>>>>>>> the
>>>>>>>>>>> value
>>>>>>>>>>> to
>>>>>>>>>>> AsyncQueueWriter.AUTO_TUNE
>>>>>>>>>>> (this
>>>>>>>>>>> will
>>>>>>>>>>> be
>>>>>>>>>>> four
>>>>>>>>>>> times
>>>>>>>>>>> the
>>>>>>>>>>> socket
>>>>>>>>>>> write
>>>>>>>>>>> buffer)
>>>>>>>>>>> and
>>>>>>>>>>> see
>>>>>>>>>>> how
>>>>>>>>>>> that
>>>>>>>>>>> works.
>>>>>>>>>>>
>>>>>>>>>>> Ryan
>>>>>>>>>>> Lubke
>>>>>>>>>>> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> A
>>>>>>>>>>>> question
>>>>>>>>>>>> first.
>>>>>>>>>>>> With
>>>>>>>>>>>> these
>>>>>>>>>>>> changes,
>>>>>>>>>>>> your
>>>>>>>>>>>> memory
>>>>>>>>>>>> usage
>>>>>>>>>>>> is
>>>>>>>>>>>> more
>>>>>>>>>>>> inline
>>>>>>>>>>>> with
>>>>>>>>>>>> what
>>>>>>>>>>>> you
>>>>>>>>>>>> were
>>>>>>>>>>>> looking
>>>>>>>>>>>> for?
>>>>>>>>>>>>
>>>>>>>>>>>> Sébastien
>>>>>>>>>>>> Lorber
>>>>>>>>>>>> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>> By
>>>>>>>>>>>>> the
>>>>>>>>>>>>> way,
>>>>>>>>>>>>> do
>>>>>>>>>>>>> you
>>>>>>>>>>>>> have
>>>>>>>>>>>>> any
>>>>>>>>>>>>> idea
>>>>>>>>>>>>> when
>>>>>>>>>>>>> the
>>>>>>>>>>>>> 1.7.20
>>>>>>>>>>>>> will
>>>>>>>>>>>>> be
>>>>>>>>>>>>> released
>>>>>>>>>>>>> (with
>>>>>>>>>>>>> these
>>>>>>>>>>>>> new
>>>>>>>>>>>>> improvements?)
>>>>>>>>>>>>>
>>>>>>>>>>>>> We
>>>>>>>>>>>>> would
>>>>>>>>>>>>> like
>>>>>>>>>>>>> to
>>>>>>>>>>>>> know
>>>>>>>>>>>>> if
>>>>>>>>>>>>> we
>>>>>>>>>>>>> wait
>>>>>>>>>>>>> for
>>>>>>>>>>>>> a release
>>>>>>>>>>>>> or
>>>>>>>>>>>>> if
>>>>>>>>>>>>> we
>>>>>>>>>>>>> install
>>>>>>>>>>>>> our
>>>>>>>>>>>>> own
>>>>>>>>>>>>> temp
>>>>>>>>>>>>> release
>>>>>>>>>>>>> on
>>>>>>>>>>>>> Nexus
>>>>>>>>>>>>> :)
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2013/8/30
>>>>>>>>>>>>> Sébastien
>>>>>>>>>>>>> Lorber
>>>>>>>>>>>>> <lorber.sebastien_at_gmail.com
>>>>>>>>>>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Thank
>>>>>>>>>>>>> you,
>>>>>>>>>>>>> it
>>>>>>>>>>>>> works
>>>>>>>>>>>>> fine!
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> I just
>>>>>>>>>>>>> had
>>>>>>>>>>>>> to
>>>>>>>>>>>>> modify
>>>>>>>>>>>>> a single
>>>>>>>>>>>>> line
>>>>>>>>>>>>> after
>>>>>>>>>>>>> your
>>>>>>>>>>>>> commit.
>>>>>>>>>>>>>
>>>>>>>>>>>>> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider#initializeTransport
>>>>>>>>>>>>> ->
>>>>>>>>>>>>> clientTransport.getAsyncQueueIO().getWriter().setMaxPendingBytesPerConnection(10000);
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> If
>>>>>>>>>>>>> I let
>>>>>>>>>>>>> the
>>>>>>>>>>>>> initial
>>>>>>>>>>>>> value
>>>>>>>>>>>>> (-1)
>>>>>>>>>>>>> it
>>>>>>>>>>>>> won't
>>>>>>>>>>>>> block,
>>>>>>>>>>>>> canWrite
>>>>>>>>>>>>> always
>>>>>>>>>>>>> returns
>>>>>>>>>>>>> true
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Btw,
>>>>>>>>>>>>> on
>>>>>>>>>>>>> AHC
>>>>>>>>>>>>> I didn't
>>>>>>>>>>>>> find
>>>>>>>>>>>>> any
>>>>>>>>>>>>> way
>>>>>>>>>>>>> to
>>>>>>>>>>>>> pass
>>>>>>>>>>>>> this
>>>>>>>>>>>>> value
>>>>>>>>>>>>> as
>>>>>>>>>>>>> a config
>>>>>>>>>>>>> attribute,
>>>>>>>>>>>>> neither
>>>>>>>>>>>>> the
>>>>>>>>>>>>> size
>>>>>>>>>>>>> of
>>>>>>>>>>>>> the
>>>>>>>>>>>>> write
>>>>>>>>>>>>> buffer
>>>>>>>>>>>>> you
>>>>>>>>>>>>> talked
>>>>>>>>>>>>> about.
>>>>>>>>>>>>>
>>>>>>>>>>>>> So
>>>>>>>>>>>>> in
>>>>>>>>>>>>> the
>>>>>>>>>>>>> end,
>>>>>>>>>>>>> is
>>>>>>>>>>>>> there
>>>>>>>>>>>>> a way
>>>>>>>>>>>>> with
>>>>>>>>>>>>> current
>>>>>>>>>>>>> AHC
>>>>>>>>>>>>> code
>>>>>>>>>>>>> to
>>>>>>>>>>>>> use
>>>>>>>>>>>>> this
>>>>>>>>>>>>> "canWrite
>>>>>>>>>>>>> = false"
>>>>>>>>>>>>> behavior?
>>>>>>>>>>>>>
>>>>>>>>>>>>> If
>>>>>>>>>>>>> not,
>>>>>>>>>>>>> can
>>>>>>>>>>>>> you
>>>>>>>>>>>>> please
>>>>>>>>>>>>> provide
>>>>>>>>>>>>> a way
>>>>>>>>>>>>> to
>>>>>>>>>>>>> set
>>>>>>>>>>>>> this
>>>>>>>>>>>>> behavior
>>>>>>>>>>>>> on
>>>>>>>>>>>>> v1.7.20
>>>>>>>>>>>>> ? thanks
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> PS:
>>>>>>>>>>>>> does
>>>>>>>>>>>>> it
>>>>>>>>>>>>> make
>>>>>>>>>>>>> sens
>>>>>>>>>>>>> to
>>>>>>>>>>>>> use
>>>>>>>>>>>>> the
>>>>>>>>>>>>> same
>>>>>>>>>>>>> number
>>>>>>>>>>>>> of
>>>>>>>>>>>>> bytes
>>>>>>>>>>>>> un
>>>>>>>>>>>>> the
>>>>>>>>>>>>> feed(Buffer)
>>>>>>>>>>>>> method
>>>>>>>>>>>>> and
>>>>>>>>>>>>> in
>>>>>>>>>>>>> the
>>>>>>>>>>>>> setMaxPendingBytesPerConnection(10000);
>>>>>>>>>>>>> ? do
>>>>>>>>>>>>> you
>>>>>>>>>>>>> have
>>>>>>>>>>>>> any
>>>>>>>>>>>>> tuning
>>>>>>>>>>>>> recommandation?
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> 2013/8/29
>>>>>>>>>>>>> Ryan
>>>>>>>>>>>>> Lubke
>>>>>>>>>>>>> <ryan.lubke_at_oracle.com
>>>>>>>>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Please
>>>>>>>>>>>>> disregard.
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> Ryan
>>>>>>>>>>>>> Lubke
>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>
>>>>>>>>>>>>>> Sébastien,
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Could
>>>>>>>>>>>>>> you
>>>>>>>>>>>>>> also
>>>>>>>>>>>>>> provide
>>>>>>>>>>>>>> a sample
>>>>>>>>>>>>>> of
>>>>>>>>>>>>>> how
>>>>>>>>>>>>>> you're
>>>>>>>>>>>>>> performing
>>>>>>>>>>>>>> your
>>>>>>>>>>>>>> feed?
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Thanks,
>>>>>>>>>>>>>> -rl
>>>>>>>>>>>>>>
>>>>>>>>>>>>>> Ryan
>>>>>>>>>>>>>> Lubke
>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sébastien,
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> I'd
>>>>>>>>>>>>>>> recommend
>>>>>>>>>>>>>>> looking
>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>> Connection.canWrite()
>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>> Connection.notifyCanWrite(WriteListener)
>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> By
>>>>>>>>>>>>>>> default,
>>>>>>>>>>>>>>> Grizzly
>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>> configure
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>> async
>>>>>>>>>>>>>>> write
>>>>>>>>>>>>>>> queue
>>>>>>>>>>>>>>> length
>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>> four
>>>>>>>>>>>>>>> times
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>> write
>>>>>>>>>>>>>>> buffer
>>>>>>>>>>>>>>> size
>>>>>>>>>>>>>>> (which
>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>> based
>>>>>>>>>>>>>>> off
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>> socket
>>>>>>>>>>>>>>> write
>>>>>>>>>>>>>>> buffer).
>>>>>>>>>>>>>>> When
>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>> queue
>>>>>>>>>>>>>>> exceeds
>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>> value,
>>>>>>>>>>>>>>> canWrite()
>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>> return
>>>>>>>>>>>>>>> false.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> When
>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>> occurs,
>>>>>>>>>>>>>>> you
>>>>>>>>>>>>>>> can
>>>>>>>>>>>>>>> register
>>>>>>>>>>>>>>> a WriteListener
>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>> notified
>>>>>>>>>>>>>>> when
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>> queue
>>>>>>>>>>>>>>> length
>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>> below
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>> configured
>>>>>>>>>>>>>>> max
>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>> simulate
>>>>>>>>>>>>>>> blocking
>>>>>>>>>>>>>>> until
>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>> onWritePossible()
>>>>>>>>>>>>>>> callback
>>>>>>>>>>>>>>> has
>>>>>>>>>>>>>>> been
>>>>>>>>>>>>>>> invoked.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ----------------------------------------------------------------
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> final
>>>>>>>>>>>>>>> FutureImpl<Boolean>
>>>>>>>>>>>>>>> future
>>>>>>>>>>>>>>> = Futures.createSafeFuture();
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> //
>>>>>>>>>>>>>>> Connection
>>>>>>>>>>>>>>> may
>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>> obtained
>>>>>>>>>>>>>>> by
>>>>>>>>>>>>>>> calling
>>>>>>>>>>>>>>> FilterChainContext.getConnection().
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> connection.notifyCanWrite(new
>>>>>>>>>>>>>>> WriteHandler()
>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> @Override
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> public
>>>>>>>>>>>>>>> void
>>>>>>>>>>>>>>> onWritePossible()
>>>>>>>>>>>>>>> throws
>>>>>>>>>>>>>>> Exception
>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> future.result(Boolean.TRUE);
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> @Override
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> public
>>>>>>>>>>>>>>> void
>>>>>>>>>>>>>>> onError(Throwable
>>>>>>>>>>>>>>> t)
>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> future.failure(Exceptions.makeIOException(t));
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> });
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> try
>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> final
>>>>>>>>>>>>>>> long
>>>>>>>>>>>>>>> writeTimeout
>>>>>>>>>>>>>>> = 30;
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> future.get(writeTimeout,
>>>>>>>>>>>>>>> TimeUnit.MILLISECONDS);
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> } catch
>>>>>>>>>>>>>>> (ExecutionException
>>>>>>>>>>>>>>> e)
>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> HttpTransactionContext
>>>>>>>>>>>>>>> httpCtx
>>>>>>>>>>>>>>> = HttpTransactionContext.get(connection);
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> httpCtx.abort(e.getCause());
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> } catch
>>>>>>>>>>>>>>> (Exception
>>>>>>>>>>>>>>> e)
>>>>>>>>>>>>>>> {
>>>>>>>>>>>>>>> HttpTransactionContext
>>>>>>>>>>>>>>> httpCtx
>>>>>>>>>>>>>>> = HttpTransactionContext.get(connection);
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> httpCtx.abort(e);
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> }
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> ---------------------------------------------------------------------
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> [1]
>>>>>>>>>>>>>>> http://grizzly.java.net/docs/2.3/apidocs/org/glassfish/grizzly/OutputSink.html.
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>> Sébastien
>>>>>>>>>>>>>>> Lorber
>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Ryan,
>>>>>>>>>>>>>>>> I've
>>>>>>>>>>>>>>>> did
>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>> other
>>>>>>>>>>>>>>>> tests.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> It
>>>>>>>>>>>>>>>> seems
>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>> a blocking
>>>>>>>>>>>>>>>> queue
>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> FeedableBodyGenerator
>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>> totally
>>>>>>>>>>>>>>>> useless
>>>>>>>>>>>>>>>> because
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> thread
>>>>>>>>>>>>>>>> consuming
>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>> not
>>>>>>>>>>>>>>>> blocking
>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> queue
>>>>>>>>>>>>>>>> never
>>>>>>>>>>>>>>>> blocks
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> feeding,
>>>>>>>>>>>>>>>> which
>>>>>>>>>>>>>>>> was
>>>>>>>>>>>>>>>> my
>>>>>>>>>>>>>>>> intention
>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> beginning.
>>>>>>>>>>>>>>>> Maybe
>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>> depends
>>>>>>>>>>>>>>>> on
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> IO
>>>>>>>>>>>>>>>> strategy
>>>>>>>>>>>>>>>> used?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I use
>>>>>>>>>>>>>>>> AHC
>>>>>>>>>>>>>>>> default
>>>>>>>>>>>>>>>> which
>>>>>>>>>>>>>>>> seems
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> use SameThreadIOStrategy
>>>>>>>>>>>>>>>> so
>>>>>>>>>>>>>>>> I don't
>>>>>>>>>>>>>>>> think
>>>>>>>>>>>>>>>> it's
>>>>>>>>>>>>>>>> related
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> IO
>>>>>>>>>>>>>>>> strategy.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> So
>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> end
>>>>>>>>>>>>>>>> I can
>>>>>>>>>>>>>>>> upload
>>>>>>>>>>>>>>>> a 70m
>>>>>>>>>>>>>>>> file
>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>> a heap
>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>> 50m,
>>>>>>>>>>>>>>>> but
>>>>>>>>>>>>>>>> I have
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> put
>>>>>>>>>>>>>>>> a Thread.sleep(30)
>>>>>>>>>>>>>>>> between
>>>>>>>>>>>>>>>> each
>>>>>>>>>>>>>>>> 100k
>>>>>>>>>>>>>>>> Buffer
>>>>>>>>>>>>>>>> send
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> FeedableBodyGenerator
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> The
>>>>>>>>>>>>>>>> connection
>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> server
>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>> not
>>>>>>>>>>>>>>>> good
>>>>>>>>>>>>>>>> here,
>>>>>>>>>>>>>>>> but
>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>> production
>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>> normally
>>>>>>>>>>>>>>>> a lot
>>>>>>>>>>>>>>>> better
>>>>>>>>>>>>>>>> as
>>>>>>>>>>>>>>>> far
>>>>>>>>>>>>>>>> as
>>>>>>>>>>>>>>>> I know.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I've
>>>>>>>>>>>>>>>> tried
>>>>>>>>>>>>>>>> things
>>>>>>>>>>>>>>>> like clientTransport.getAsyncQueueIO().getWriter().setMaxPendingBytesPerConnection(100000);
>>>>>>>>>>>>>>>> but
>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>> doesn't
>>>>>>>>>>>>>>>> seem
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> work
>>>>>>>>>>>>>>>> for
>>>>>>>>>>>>>>>> me.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'd
>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> Grizzly
>>>>>>>>>>>>>>>> internals
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> block
>>>>>>>>>>>>>>>> when
>>>>>>>>>>>>>>>> there
>>>>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>> too
>>>>>>>>>>>>>>>> much
>>>>>>>>>>>>>>>> pending
>>>>>>>>>>>>>>>> bytes
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> send.
>>>>>>>>>>>>>>>> Is
>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>> possible?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> PS:
>>>>>>>>>>>>>>>> I've
>>>>>>>>>>>>>>>> just
>>>>>>>>>>>>>>>> been
>>>>>>>>>>>>>>>> able
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> send
>>>>>>>>>>>>>>>> a 500mo
>>>>>>>>>>>>>>>> file
>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>> 100mo
>>>>>>>>>>>>>>>> heap,
>>>>>>>>>>>>>>>> but
>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>> needed
>>>>>>>>>>>>>>>> a sleep
>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>> 100ms
>>>>>>>>>>>>>>>> between
>>>>>>>>>>>>>>>> each
>>>>>>>>>>>>>>>> 100k
>>>>>>>>>>>>>>>> Buffer
>>>>>>>>>>>>>>>> sent
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> bodygenerator
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2013/8/29
>>>>>>>>>>>>>>>> Sébastien
>>>>>>>>>>>>>>>> Lorber
>>>>>>>>>>>>>>>> <lorber.sebastien_at_gmail.com
>>>>>>>>>>>>>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> By
>>>>>>>>>>>>>>>> chance
>>>>>>>>>>>>>>>> do
>>>>>>>>>>>>>>>> you
>>>>>>>>>>>>>>>> if
>>>>>>>>>>>>>>>> I can
>>>>>>>>>>>>>>>> remove
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> MessageCloner
>>>>>>>>>>>>>>>> used
>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> SSL
>>>>>>>>>>>>>>>> filter?
>>>>>>>>>>>>>>>> SSLBaseFilter$OnWriteCopyCloner
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> It
>>>>>>>>>>>>>>>> seems
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> allocate
>>>>>>>>>>>>>>>> a lot
>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>> memory.
>>>>>>>>>>>>>>>> I don't
>>>>>>>>>>>>>>>> really
>>>>>>>>>>>>>>>> understand
>>>>>>>>>>>>>>>> why
>>>>>>>>>>>>>>>> messages
>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>>> cloned,
>>>>>>>>>>>>>>>> can
>>>>>>>>>>>>>>>> I remove
>>>>>>>>>>>>>>>> this?
>>>>>>>>>>>>>>>> How?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2013/8/29
>>>>>>>>>>>>>>>> Sébastien
>>>>>>>>>>>>>>>> Lorber
>>>>>>>>>>>>>>>> <lorber.sebastien_at_gmail.com
>>>>>>>>>>>>>>>> <mailto:lorber.sebastien_at_gmail.com>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'm
>>>>>>>>>>>>>>>> trying
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> send
>>>>>>>>>>>>>>>> a 500m
>>>>>>>>>>>>>>>> file
>>>>>>>>>>>>>>>> for
>>>>>>>>>>>>>>>> my
>>>>>>>>>>>>>>>> tests
>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>> a heap
>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>> 400m.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> In
>>>>>>>>>>>>>>>> our
>>>>>>>>>>>>>>>> real
>>>>>>>>>>>>>>>> use
>>>>>>>>>>>>>>>> cases
>>>>>>>>>>>>>>>> we
>>>>>>>>>>>>>>>> would
>>>>>>>>>>>>>>>> probably
>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>> files
>>>>>>>>>>>>>>>> under
>>>>>>>>>>>>>>>> 20mo
>>>>>>>>>>>>>>>> but
>>>>>>>>>>>>>>>> we
>>>>>>>>>>>>>>>> want
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> reduce
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>> consumption
>>>>>>>>>>>>>>>> because
>>>>>>>>>>>>>>>> we
>>>>>>>>>>>>>>>> can
>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>> x parallel
>>>>>>>>>>>>>>>> uploads
>>>>>>>>>>>>>>>> on
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> same
>>>>>>>>>>>>>>>> server
>>>>>>>>>>>>>>>> according
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> user
>>>>>>>>>>>>>>>> activity.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'll
>>>>>>>>>>>>>>>> try
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> check
>>>>>>>>>>>>>>>> if
>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>>> BodyGenerator
>>>>>>>>>>>>>>>> reduced
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>> footprint
>>>>>>>>>>>>>>>> or
>>>>>>>>>>>>>>>> if
>>>>>>>>>>>>>>>> it's
>>>>>>>>>>>>>>>> almost
>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>> before.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> 2013/8/28
>>>>>>>>>>>>>>>> Ryan
>>>>>>>>>>>>>>>> Lubke
>>>>>>>>>>>>>>>> <ryan.lubke_at_oracle.com
>>>>>>>>>>>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> At
>>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>>> point
>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>> time,
>>>>>>>>>>>>>>>> as
>>>>>>>>>>>>>>>> far
>>>>>>>>>>>>>>>> as
>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>> SSL
>>>>>>>>>>>>>>>> buffer
>>>>>>>>>>>>>>>> allocation
>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>> concerned,
>>>>>>>>>>>>>>>> it's
>>>>>>>>>>>>>>>> untunable.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> That
>>>>>>>>>>>>>>>> said,
>>>>>>>>>>>>>>>> feel
>>>>>>>>>>>>>>>> free
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> open
>>>>>>>>>>>>>>>> a feature
>>>>>>>>>>>>>>>> request.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> As
>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>> your
>>>>>>>>>>>>>>>> second
>>>>>>>>>>>>>>>> question,
>>>>>>>>>>>>>>>> there
>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>> no
>>>>>>>>>>>>>>>> suggested
>>>>>>>>>>>>>>>> size.
>>>>>>>>>>>>>>>> This
>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>> all
>>>>>>>>>>>>>>>> very
>>>>>>>>>>>>>>>> application
>>>>>>>>>>>>>>>> specific.
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> I'm
>>>>>>>>>>>>>>>> curious,
>>>>>>>>>>>>>>>> how
>>>>>>>>>>>>>>>> large
>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>> a file
>>>>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>> you
>>>>>>>>>>>>>>>> sending?
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>> Sébastien
>>>>>>>>>>>>>>>> Lorber
>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I have
>>>>>>>>>>>>>>>>> seen
>>>>>>>>>>>>>>>>> a lot
>>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>>> buffers
>>>>>>>>>>>>>>>>> which
>>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>>> a size
>>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>>> 33842
>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>> seems
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> limit
>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>> near
>>>>>>>>>>>>>>>>> half
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> capacity.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Perhaps
>>>>>>>>>>>>>>>>> there's
>>>>>>>>>>>>>>>>> a way
>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>> tune
>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>> buffer
>>>>>>>>>>>>>>>>> size
>>>>>>>>>>>>>>>>> so
>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>> consumes
>>>>>>>>>>>>>>>>> less
>>>>>>>>>>>>>>>>> memory?
>>>>>>>>>>>>>>>>> Is
>>>>>>>>>>>>>>>>> there
>>>>>>>>>>>>>>>>> an
>>>>>>>>>>>>>>>>> ideal
>>>>>>>>>>>>>>>>> Buffer
>>>>>>>>>>>>>>>>> size
>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>> send
>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> feed
>>>>>>>>>>>>>>>>> method?
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> 2013/8/28
>>>>>>>>>>>>>>>>> Ryan
>>>>>>>>>>>>>>>>> Lubke
>>>>>>>>>>>>>>>>> <ryan.lubke_at_oracle.com
>>>>>>>>>>>>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> I'll
>>>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>>>> reviewing
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> PR
>>>>>>>>>>>>>>>>> today,
>>>>>>>>>>>>>>>>> thanks
>>>>>>>>>>>>>>>>> again!
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Regarding
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> OOM:
>>>>>>>>>>>>>>>>> as
>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>> stands
>>>>>>>>>>>>>>>>> now,
>>>>>>>>>>>>>>>>> for
>>>>>>>>>>>>>>>>> each
>>>>>>>>>>>>>>>>> new
>>>>>>>>>>>>>>>>> buffer
>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>> passed
>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> SSLFilter,
>>>>>>>>>>>>>>>>> we
>>>>>>>>>>>>>>>>> allocate
>>>>>>>>>>>>>>>>> a buffer
>>>>>>>>>>>>>>>>> twice
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> size
>>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>>> order
>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>> accommodate
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> encrypted
>>>>>>>>>>>>>>>>> result.
>>>>>>>>>>>>>>>>> So
>>>>>>>>>>>>>>>>> there's
>>>>>>>>>>>>>>>>> an
>>>>>>>>>>>>>>>>> increase.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Depending
>>>>>>>>>>>>>>>>> on
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> socket
>>>>>>>>>>>>>>>>> configurations
>>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>>> both
>>>>>>>>>>>>>>>>> endpoints,
>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>> how
>>>>>>>>>>>>>>>>> fast
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> remote
>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>> reading
>>>>>>>>>>>>>>>>> data,
>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>> could
>>>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> write
>>>>>>>>>>>>>>>>> queue
>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>> becoming
>>>>>>>>>>>>>>>>> too
>>>>>>>>>>>>>>>>> large.
>>>>>>>>>>>>>>>>> We
>>>>>>>>>>>>>>>>> do
>>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>>> a way
>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>> detect
>>>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>>>> situation,
>>>>>>>>>>>>>>>>> but
>>>>>>>>>>>>>>>>> I'm
>>>>>>>>>>>>>>>>> pretty
>>>>>>>>>>>>>>>>> sure
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>> Grizzly
>>>>>>>>>>>>>>>>> internals
>>>>>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>>> currently
>>>>>>>>>>>>>>>>> shielded
>>>>>>>>>>>>>>>>> here.
>>>>>>>>>>>>>>>>> I will
>>>>>>>>>>>>>>>>> see
>>>>>>>>>>>>>>>>> what
>>>>>>>>>>>>>>>>> I can
>>>>>>>>>>>>>>>>> do
>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>> allow
>>>>>>>>>>>>>>>>> users
>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>> leverage
>>>>>>>>>>>>>>>>> this.
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>> Sébastien
>>>>>>>>>>>>>>>>> Lorber
>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Hello,
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> I've
>>>>>>>>>>>>>>>>>> made
>>>>>>>>>>>>>>>>>> my
>>>>>>>>>>>>>>>>>> pull
>>>>>>>>>>>>>>>>>> request.
>>>>>>>>>>>>>>>>>> https://github.com/AsyncHttpClient/async-http-client/pull/367
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> With
>>>>>>>>>>>>>>>>>> my
>>>>>>>>>>>>>>>>>> usecase
>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>> works,
>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>> file
>>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>>> uploaded
>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>> before.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> But
>>>>>>>>>>>>>>>>>> I didn't
>>>>>>>>>>>>>>>>>> notice
>>>>>>>>>>>>>>>>>> a big
>>>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>>>> improvement.
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Is
>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>> possible
>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>> SSL
>>>>>>>>>>>>>>>>>> doesn't
>>>>>>>>>>>>>>>>>> allow
>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>> stream
>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>> body
>>>>>>>>>>>>>>>>>> or
>>>>>>>>>>>>>>>>>> something
>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>> that?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> In
>>>>>>>>>>>>>>>>>> memory,
>>>>>>>>>>>>>>>>>> I have
>>>>>>>>>>>>>>>>>> a lot
>>>>>>>>>>>>>>>>>> of:
>>>>>>>>>>>>>>>>>> - HeapByteBuffer
>>>>>>>>>>>>>>>>>> Which
>>>>>>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>>>> hold
>>>>>>>>>>>>>>>>>> by
>>>>>>>>>>>>>>>>>> SSLUtils$3
>>>>>>>>>>>>>>>>>> Which
>>>>>>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>>>> hold
>>>>>>>>>>>>>>>>>> by
>>>>>>>>>>>>>>>>>> BufferBuffers
>>>>>>>>>>>>>>>>>> Which
>>>>>>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>>>> hold
>>>>>>>>>>>>>>>>>> by
>>>>>>>>>>>>>>>>>> WriteResult
>>>>>>>>>>>>>>>>>> Which
>>>>>>>>>>>>>>>>>> are
>>>>>>>>>>>>>>>>>> hold
>>>>>>>>>>>>>>>>>> by
>>>>>>>>>>>>>>>>>> AsyncWriteQueueRecord
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Here
>>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>>> an
>>>>>>>>>>>>>>>>>> exemple
>>>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>> OOM
>>>>>>>>>>>>>>>>>> stacktrace:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> java.lang.OutOfMemoryError:
>>>>>>>>>>>>>>>>>> Java
>>>>>>>>>>>>>>>>>> heap
>>>>>>>>>>>>>>>>>> space
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> java.nio.HeapByteBuffer.<init>(HeapByteBuffer.java:57)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> java.nio.ByteBuffer.allocate(ByteBuffer.java:331)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ssl.SSLUtils.allocateOutputBuffer(SSLUtils.java:342)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ssl.SSLBaseFilter$2.grow(SSLBaseFilter.java:117)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ssl.SSLConnectionContext.ensureBufferSize(SSLConnectionContext.java:392)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ssl.SSLConnectionContext.wrap(SSLConnectionContext.java:272)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ssl.SSLConnectionContext.wrapAll(SSLConnectionContext.java:227)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ssl.SSLBaseFilter.wrapAll(SSLBaseFilter.java:404)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ssl.SSLBaseFilter.handleWrite(SSLBaseFilter.java:319)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ssl.SSLFilter.accurateWrite(SSLFilter.java:255)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ssl.SSLFilter.handleWrite(SSLFilter.java:143)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> com.ning.http.client.providers.grizzly.GrizzlyAsyncHttpProvider$SwitchingSSLFilter.handleWrite(GrizzlyAsyncHttpProvider.java:2503)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.filterchain.ExecutorResolver$8.execute(ExecutorResolver.java:111)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeFilter(DefaultFilterChain.java:288)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.executeChainPart(DefaultFilterChain.java:206)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:136)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.filterchain.DefaultFilterChain.process(DefaultFilterChain.java:114)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.ProcessorExecutor.execute(ProcessorExecutor.java:77)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.filterchain.FilterChainContext.write(FilterChainContext.java:853)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> org.glassfish.grizzly.filterchain.FilterChainContext.write(FilterChainContext.java:720)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.flushQueue(FeedableBodyGenerator.java:132)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> com.ning.http.client.providers.grizzly.FeedableBodyGenerator.feed(FeedableBodyGenerator.java:101)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> com.ning.http.client.providers.grizzly.MultipartBodyGeneratorFeeder$FeedBodyGeneratorOutputStream.write(MultipartBodyGeneratorFeeder.java:222)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> java.io.BufferedOutputStream.write(BufferedOutputStream.java:126)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> com.ning.http.multipart.FilePart.sendData(FilePart.java:179)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> com.ning.http.multipart.Part.send(Part.java:331)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> com.ning.http.multipart.Part.sendParts(Part.java:397)
>>>>>>>>>>>>>>>>>> at
>>>>>>>>>>>>>>>>>> com.ning.http.client.providers.grizzly.MultipartBodyGeneratorFeeder.feed(MultipartBodyGeneratorFeeder.java:144)
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Any
>>>>>>>>>>>>>>>>>> idea?
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> 2013/8/27
>>>>>>>>>>>>>>>>>> Ryan
>>>>>>>>>>>>>>>>>> Lubke
>>>>>>>>>>>>>>>>>> <ryan.lubke_at_oracle.com
>>>>>>>>>>>>>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Excellent!
>>>>>>>>>>>>>>>>>> Looking
>>>>>>>>>>>>>>>>>> forward
>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>> pull
>>>>>>>>>>>>>>>>>> request!
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>> Sébastien
>>>>>>>>>>>>>>>>>> Lorber
>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Ryan
>>>>>>>>>>>>>>>>>>> thanks,
>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>> works
>>>>>>>>>>>>>>>>>>> fine,
>>>>>>>>>>>>>>>>>>> I'll
>>>>>>>>>>>>>>>>>>> make
>>>>>>>>>>>>>>>>>>> a pull
>>>>>>>>>>>>>>>>>>> request
>>>>>>>>>>>>>>>>>>> on
>>>>>>>>>>>>>>>>>>> AHC
>>>>>>>>>>>>>>>>>>> tomorrow
>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>> a better
>>>>>>>>>>>>>>>>>>> code
>>>>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> same
>>>>>>>>>>>>>>>>>>> Part
>>>>>>>>>>>>>>>>>>> classes
>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>> already
>>>>>>>>>>>>>>>>>>> exist.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> I created
>>>>>>>>>>>>>>>>>>> an
>>>>>>>>>>>>>>>>>>> OutputStream
>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>> redirects
>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> BodyGenerator
>>>>>>>>>>>>>>>>>>> feeder.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> The
>>>>>>>>>>>>>>>>>>> problem
>>>>>>>>>>>>>>>>>>> I currently
>>>>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> feeder
>>>>>>>>>>>>>>>>>>> feeds
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> queue
>>>>>>>>>>>>>>>>>>> faster
>>>>>>>>>>>>>>>>>>> than
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> async
>>>>>>>>>>>>>>>>>>> thread
>>>>>>>>>>>>>>>>>>> polling
>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>> :)
>>>>>>>>>>>>>>>>>>> I need
>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>> expose
>>>>>>>>>>>>>>>>>>> a limit
>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>> queue
>>>>>>>>>>>>>>>>>>> size
>>>>>>>>>>>>>>>>>>> or
>>>>>>>>>>>>>>>>>>> something,
>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>> work
>>>>>>>>>>>>>>>>>>> on
>>>>>>>>>>>>>>>>>>> that,
>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>> will
>>>>>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>>>>>> better
>>>>>>>>>>>>>>>>>>> than
>>>>>>>>>>>>>>>>>>> a thread
>>>>>>>>>>>>>>>>>>> sleep
>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>> slow
>>>>>>>>>>>>>>>>>>> down
>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>> filepart
>>>>>>>>>>>>>>>>>>> reading
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> 2013/8/27
>>>>>>>>>>>>>>>>>>> Ryan
>>>>>>>>>>>>>>>>>>> Lubke
>>>>>>>>>>>>>>>>>>> <ryan.lubke_at_oracle.com
>>>>>>>>>>>>>>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Yes,
>>>>>>>>>>>>>>>>>>> something
>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>> that.
>>>>>>>>>>>>>>>>>>> I was
>>>>>>>>>>>>>>>>>>> going
>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>> tackle
>>>>>>>>>>>>>>>>>>> adding
>>>>>>>>>>>>>>>>>>> something
>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>>>>>> today.
>>>>>>>>>>>>>>>>>>> I'll
>>>>>>>>>>>>>>>>>>> follow
>>>>>>>>>>>>>>>>>>> up
>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>> something
>>>>>>>>>>>>>>>>>>> you
>>>>>>>>>>>>>>>>>>> can
>>>>>>>>>>>>>>>>>>> test
>>>>>>>>>>>>>>>>>>> out.
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>> Sébastien
>>>>>>>>>>>>>>>>>>> Lorber
>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Ok
>>>>>>>>>>>>>>>>>>>> thanks!
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I think
>>>>>>>>>>>>>>>>>>>> I see
>>>>>>>>>>>>>>>>>>>> what
>>>>>>>>>>>>>>>>>>>> I could
>>>>>>>>>>>>>>>>>>>> do,
>>>>>>>>>>>>>>>>>>>> probably
>>>>>>>>>>>>>>>>>>>> something
>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>> that:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> FeedableBodyGenerator
>>>>>>>>>>>>>>>>>>>> bodyGenerator
>>>>>>>>>>>>>>>>>>>> = new
>>>>>>>>>>>>>>>>>>>> FeedableBodyGenerator();
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> MultipartBodyGeneratorFeeder
>>>>>>>>>>>>>>>>>>>> bodyGeneratorFeeder
>>>>>>>>>>>>>>>>>>>> = new
>>>>>>>>>>>>>>>>>>>> MultipartBodyGeneratorFeeder(bodyGenerator);
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Request
>>>>>>>>>>>>>>>>>>>> uploadRequest1
>>>>>>>>>>>>>>>>>>>> = new
>>>>>>>>>>>>>>>>>>>> RequestBuilder("POST")
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> .setUrl("url")
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> .setBody(bodyGenerator)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> .build();
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> ListenableFuture<Response>
>>>>>>>>>>>>>>>>>>>> asyncRes
>>>>>>>>>>>>>>>>>>>> = asyncHttpClient
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> .prepareRequest(uploadRequest1)
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> .execute(new
>>>>>>>>>>>>>>>>>>>> AsyncCompletionHandlerBase());
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> bodyGeneratorFeeder.append("param1","value1");
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> bodyGeneratorFeeder.append("param2","value2");
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> bodyGeneratorFeeder.append("fileToUpload",fileInputStream);
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> bodyGeneratorFeeder.end();
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Response
>>>>>>>>>>>>>>>>>>>> uploadResponse
>>>>>>>>>>>>>>>>>>>> = asyncRes.get();
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Does
>>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>>> seem
>>>>>>>>>>>>>>>>>>>> ok
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> you?
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I guess
>>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>>> could
>>>>>>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>>>>>>> interesting
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> provide
>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>> MultipartBodyGeneratorFeeder
>>>>>>>>>>>>>>>>>>>> class
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> AHC
>>>>>>>>>>>>>>>>>>>> or
>>>>>>>>>>>>>>>>>>>> Grizzly
>>>>>>>>>>>>>>>>>>>> since
>>>>>>>>>>>>>>>>>>>> some
>>>>>>>>>>>>>>>>>>>> other
>>>>>>>>>>>>>>>>>>>> people
>>>>>>>>>>>>>>>>>>>> may
>>>>>>>>>>>>>>>>>>>> want
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> achieve
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> same
>>>>>>>>>>>>>>>>>>>> thing
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> 2013/8/26
>>>>>>>>>>>>>>>>>>>> Ryan
>>>>>>>>>>>>>>>>>>>> Lubke
>>>>>>>>>>>>>>>>>>>> <ryan.lubke_at_oracle.com
>>>>>>>>>>>>>>>>>>>> <mailto:ryan.lubke_at_oracle.com>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Sébastien
>>>>>>>>>>>>>>>>>>>> Lorber
>>>>>>>>>>>>>>>>>>>> wrote:
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Hello,
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I would
>>>>>>>>>>>>>>>>>>>> like
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> know
>>>>>>>>>>>>>>>>>>>> if
>>>>>>>>>>>>>>>>>>>> it's
>>>>>>>>>>>>>>>>>>>> possible
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> upload
>>>>>>>>>>>>>>>>>>>> a file
>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>> AHC
>>>>>>>>>>>>>>>>>>>> / Grizzly
>>>>>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>>>>>> streaming,
>>>>>>>>>>>>>>>>>>>> I mean
>>>>>>>>>>>>>>>>>>>> without
>>>>>>>>>>>>>>>>>>>> loading
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> whole
>>>>>>>>>>>>>>>>>>>> file
>>>>>>>>>>>>>>>>>>>> bytes
>>>>>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>>>>>> memory.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> The
>>>>>>>>>>>>>>>>>>>> default
>>>>>>>>>>>>>>>>>>>> behavior
>>>>>>>>>>>>>>>>>>>> seems
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> allocate
>>>>>>>>>>>>>>>>>>>> a byte[]
>>>>>>>>>>>>>>>>>>>> which
>>>>>>>>>>>>>>>>>>>> contans
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> whole
>>>>>>>>>>>>>>>>>>>> file,
>>>>>>>>>>>>>>>>>>>> so
>>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>>> means
>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>> my
>>>>>>>>>>>>>>>>>>>> server
>>>>>>>>>>>>>>>>>>>> can
>>>>>>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>>>>>>> OOM
>>>>>>>>>>>>>>>>>>>> if
>>>>>>>>>>>>>>>>>>>> too
>>>>>>>>>>>>>>>>>>>> many
>>>>>>>>>>>>>>>>>>>> users
>>>>>>>>>>>>>>>>>>>> upload
>>>>>>>>>>>>>>>>>>>> a large
>>>>>>>>>>>>>>>>>>>> file
>>>>>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> same
>>>>>>>>>>>>>>>>>>>> time.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> I've
>>>>>>>>>>>>>>>>>>>> tryied
>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>> a Heap
>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>> ByteBuffer
>>>>>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>>>>>> managers,
>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>> reallocate=true/false
>>>>>>>>>>>>>>>>>>>> but
>>>>>>>>>>>>>>>>>>>> no
>>>>>>>>>>>>>>>>>>>> more
>>>>>>>>>>>>>>>>>>>> success.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> It
>>>>>>>>>>>>>>>>>>>> seems
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> whole
>>>>>>>>>>>>>>>>>>>> file
>>>>>>>>>>>>>>>>>>>> content
>>>>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>>>>> appended
>>>>>>>>>>>>>>>>>>>> wto
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> BufferOutputStream,
>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> underlying
>>>>>>>>>>>>>>>>>>>> buffer
>>>>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>>>>> written.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> At
>>>>>>>>>>>>>>>>>>>> least
>>>>>>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>>>>>>> seems
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> case
>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>> AHC
>>>>>>>>>>>>>>>>>>>> integration:
>>>>>>>>>>>>>>>>>>>> https://github.com/AsyncHttpClient/async-http-client/blob/6faf1f316e5546110b0779a5a42fd9d03ba6bc15/providers/grizzly/src/main/java/org/asynchttpclient/providers/grizzly/bodyhandler/PartsBodyHandler.java
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> So,
>>>>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>>>>> there
>>>>>>>>>>>>>>>>>>>> a way
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> patch
>>>>>>>>>>>>>>>>>>>> AHC
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> stream
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> file
>>>>>>>>>>>>>>>>>>>> so
>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>> I could
>>>>>>>>>>>>>>>>>>>> eventually
>>>>>>>>>>>>>>>>>>>> consume
>>>>>>>>>>>>>>>>>>>> only
>>>>>>>>>>>>>>>>>>>> 20mo
>>>>>>>>>>>>>>>>>>>> of
>>>>>>>>>>>>>>>>>>>> heap
>>>>>>>>>>>>>>>>>>>> while
>>>>>>>>>>>>>>>>>>>> uploading
>>>>>>>>>>>>>>>>>>>> a 500mo
>>>>>>>>>>>>>>>>>>>> file?
>>>>>>>>>>>>>>>>>>>> Or
>>>>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>>>>>>> simply
>>>>>>>>>>>>>>>>>>>> impossible
>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>> Grizzly?
>>>>>>>>>>>>>>>>>>>> I didn't
>>>>>>>>>>>>>>>>>>>> notice
>>>>>>>>>>>>>>>>>>>> anything
>>>>>>>>>>>>>>>>>>>> related
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> documentation.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> It's
>>>>>>>>>>>>>>>>>>>> possible
>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> FeedableBodyGenerator.
>>>>>>>>>>>>>>>>>>>> But
>>>>>>>>>>>>>>>>>>>> if
>>>>>>>>>>>>>>>>>>>> you're
>>>>>>>>>>>>>>>>>>>> tied
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>>>>>> Multipart
>>>>>>>>>>>>>>>>>>>> uploads,
>>>>>>>>>>>>>>>>>>>> you'd
>>>>>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> convert
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> multipart
>>>>>>>>>>>>>>>>>>>> data
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> Buffers
>>>>>>>>>>>>>>>>>>>> manually
>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>> send
>>>>>>>>>>>>>>>>>>>> using
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> FeedableBodyGenerator.
>>>>>>>>>>>>>>>>>>>> I'll
>>>>>>>>>>>>>>>>>>>> take
>>>>>>>>>>>>>>>>>>>> a closer
>>>>>>>>>>>>>>>>>>>> look
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> see
>>>>>>>>>>>>>>>>>>>> if
>>>>>>>>>>>>>>>>>>>> this
>>>>>>>>>>>>>>>>>>>> area
>>>>>>>>>>>>>>>>>>>> can
>>>>>>>>>>>>>>>>>>>> be
>>>>>>>>>>>>>>>>>>>> improved.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Btw
>>>>>>>>>>>>>>>>>>>> in
>>>>>>>>>>>>>>>>>>>> my
>>>>>>>>>>>>>>>>>>>> case
>>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>>>>> a file
>>>>>>>>>>>>>>>>>>>> upload.
>>>>>>>>>>>>>>>>>>>> I receive
>>>>>>>>>>>>>>>>>>>> a file
>>>>>>>>>>>>>>>>>>>> with
>>>>>>>>>>>>>>>>>>>> CXF
>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>> have
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> transmit
>>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> a storage
>>>>>>>>>>>>>>>>>>>> server
>>>>>>>>>>>>>>>>>>>> (like
>>>>>>>>>>>>>>>>>>>> S3).
>>>>>>>>>>>>>>>>>>>> CXF
>>>>>>>>>>>>>>>>>>>> doesn't
>>>>>>>>>>>>>>>>>>>> consume
>>>>>>>>>>>>>>>>>>>> memory
>>>>>>>>>>>>>>>>>>>> bevause
>>>>>>>>>>>>>>>>>>>> it
>>>>>>>>>>>>>>>>>>>> is
>>>>>>>>>>>>>>>>>>>> streaming
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> large
>>>>>>>>>>>>>>>>>>>> fle
>>>>>>>>>>>>>>>>>>>> uploads
>>>>>>>>>>>>>>>>>>>> to
>>>>>>>>>>>>>>>>>>>> the
>>>>>>>>>>>>>>>>>>>> file
>>>>>>>>>>>>>>>>>>>> system,
>>>>>>>>>>>>>>>>>>>> and
>>>>>>>>>>>>>>>>>>>> then
>>>>>>>>>>>>>>>>>>>> provides
>>>>>>>>>>>>>>>>>>>> an
>>>>>>>>>>>>>>>>>>>> input
>>>>>>>>>>>>>>>>>>>> stream
>>>>>>>>>>>>>>>>>>>> on
>>>>>>>>>>>>>>>>>>>> that
>>>>>>>>>>>>>>>>>>>> file.
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>> Thanks
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>
>>>>>>
>>>>
>>>>
>>>>
>>>>
>>>
>
>