Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 882
neptune Avatar asked Apr 03 '13 01:04

neptune


People also ask

What is a greenlet in gevent?

Greenlets are lightweight thread-like structures that are scheduled and managed inside the process. They are references to the part of the stack that is used by the thread. Compared to POSIX threads (pthreads), there is no stack allocated up front and there is only as much stack as is actually used by the greenlet.

What is gevent used for?

gevent is a coroutine -based Python networking library that uses greenlet to provide a high-level synchronous API on top of the libev or libuv event loop. Features include: Fast event loop based on libev or libuv. Lightweight execution units based on greenlets.

Is gevent asynchronous?

Gevent is the use of simple, sequential programming in python to achieve scalability provided by asynchronous IO and lightweight multi-threading (as opposed to the callback-style of programming using Twisted's Deferred).

What is gevent pool?

gevent is a concurrency library based around libev. It provides a clean API for a variety of concurrency and network related tasks.


1 Answers

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.

like image 170
FatalError Avatar answered Oct 04 '22 03:10

FatalError