syrusakbary / promise

Ultra-performant Promise implementation in Python
MIT License
362 stars 76 forks source link

Threading issue in 2.0 #33

Closed addyess closed 7 years ago

addyess commented 7 years ago

This test locks up in python2.7

def test_get_after_get_in_promise():
    def do(x):
        v = Promise.resolve("ok").then(lambda x: x).get()  # the wait inside get waits forever
        return v

    p = Promise.resolve(None).then(do)
    assert p.get() == "ok"
addyess commented 7 years ago

Could be related to: https://github.com/syrusakbary/promise/issues/30

addyess commented 7 years ago

The issue seems to be in here:

the Promise p executes function do in the context of the first drain_queue(self.normal_queue) when self.is_tick_used is set True

    def drain_queues(self):
        assert self.is_tick_used
        self.drain_queue(self.normal_queue)
        self.reset()
        self.have_drained_queues = True
        self.drain_queue(self.late_queue)

one global async_instance = Async(SyncScheduler()) is used for all promises.

when the inner Promise calls its .get() -- it blocks indefinitely for the async_instance to call the secondary promise's _settle_promise

This blocks the first call to drain_queues infinitely locking up all promises :)

addyess commented 7 years ago

here's a picture of the callstack as the inner .get is call image

syrusakbary commented 7 years ago

This issue is now fixed in master