2

I'm playing with AsyncHTTPBuilder (v0.5.1) however, I can't get it working so it's execute requests asynchronously. Please, check the code below. Looks like all requests are done from the same thread:

@Test public void testPoolsizeAndQueueing() {
def http = new AsyncHTTPBuilder( poolSize : 5 ,
                                 uri : 'http://ajax.googleapis.com/ajax/services/search/web' )

def responses = []
/* With one thread in the pool, responses will be sequential but should
 * queue up w/o being rejected. */
10.times {
responses << http.get( query : [q:'Groovy', v:'1.0'] ) { return Thread.currentThread().name }
responses << http.get( query : [q:'Ruby', v:'1.0'] )  { return Thread.currentThread().name }
responses << http.get( query : [q:'Scala', v:'1.0'] )  { return Thread.currentThread().name }
}
def timeout = 60000
def time = 0
while ( true ) {
    if ( responses.every{ it.done ? it.get() : 0 } ) break
    print '.'
    Thread.sleep 2000
    time += 2000
if ( time > timeout ) assert false
}
responses.each { println it.get() }
http.shutdown()
}

Output: ..pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1 pool-3-thread-1

Archer
  • 5,073
  • 8
  • 50
  • 96

2 Answers2

3

I've fixed the bug and deployed a new 0.5.2-SNAPSHOT. So it will work now with the latest snapshot.

I plan to release 0.5.2 final with this fix and fixes for a number of other bugs soon.

For the record, the named parameter is actually poolSize not poolsize but that's not the cause of the problem. (But this is something I plan to fix in 0.5.2 - http://jira.codehaus.org/browse/GMOD-175 .)

Thanks to Tim Yates for reporting the bug.

thom_nic
  • 7,809
  • 6
  • 42
  • 43
  • 1
    Just did an `rm -r ~/.groovy/grapes/org.codehaus.groovy.modules.http-builder/` and tested the script again, and it all works! Thanks Thom :-) – tim_yates Mar 10 '11 at 09:18
2

I believe this is as expected.

The queries are being run in separate threads asynchronously, but the { return Thread.currentThread().name } closure is getting run when it.get() is called (in the same thread as the main script is running)

Hope this explains it

EDIT

You're right.

Running with

def http = new AsyncHTTPBuilder( poolsize:5,
                                 uri:'http://ajax.googleapis.com/ajax/services/search/web' )

doesn't work as expected...and changing it to:

def http = new AsyncHTTPBuilder( threadPool:java.util.concurrent.Executors.newFixedThreadPool( 5 ),
                                 uri:'http://ajax.googleapis.com/ajax/services/search/web' )

makes it work. Even tried with 0.5.2-SNAPSHOT, but got the same issue

I have reported it as a bug: http://jira.codehaus.org/browse/GMOD-174

Fingers crossed it will get fixed (or we'll find out why we're doing it wrong) by v 0.5.2

tim_yates
  • 167,322
  • 27
  • 342
  • 338
  • That can't be true. `{ return Thread.currentThread().name }` closure is getting run once request is made and requested data is available. After more tests I've found that it works perfectly if I create `def sharedThreadPool = new ThreadPoolExecutor(poolSize, poolSize, 120L, TimeUnit.SECONDS, new ArrayBlockingQueue(6000))` and passing it as threadPool parameter to `AsyncHTTPBuilder` constructor. Looks like there's some problem with `poolSize` parameter. – Archer Mar 08 '11 at 12:40
  • Sorry... You're right of course and it looks to me like a bug – tim_yates Mar 09 '11 at 11:37