neptune
neptune

Reputation: 1420

Why does gevent.spawn not execute the parameterized function until a call to Greenlet.join?

I'd like to issue an asynchronous HTTP POST request using gevent -- I don't care about the response, I simply want to execute the request as soon as possible. However, whenever I attempt to do so using gevent.spawn, the request never executes. I know this because calling the .ready() or .successful() methods on the Greenlet that is returned from gevent.spawn always returns False.

However, the Greenlet has started, because if I call glet = gevent.spawn(...), then glet.start(), I get an error saying AssertionError: Greenlet already started.

The only time I get a glet.ready() == True is when I call glet.join(), but this is a blocking operation. How can I have the Greenlet execute without waiting for it to complete?

Upvotes: 9

Views: 5451

Answers (1)

FatalError
FatalError

Reputation: 54591

Since greenlets are cooperative, your new greenlet won't run until you yield to it. After calling spawn, call gevent.sleep(0) to yield and your greenlet should run.

It will continue to run until it does something that causes it to yield (like kicking off that http req). Then your other code can resume again.

EDIT:

To address your question about grequests, the grequests.send() doc says:

send(r, pool=None, stream=False)
    Sends the request object using the specified pool. If a pool isn't
    specified this method blocks. Pools are useful because you can specify size
    and can hence limit concurrency

Since you have not specified a pool, the request blocks for your greenlet to finish. In other words, once it returns the greenlet has already completed. To get the response, see glt.get() of the returned greenlet.

Upvotes: 9

Related Questions