aio-libs/aiorwlock

Multiple coroutines acquire locks and request locks

pythonsite opened this issue · 15 comments

async with rwlock.writer

When I get the lock in the above way, when a coroutine does not release the lock, the other coroutines also get the lock.

Hi, I'm GitMate.io!

It seems you've just enabled the issue triaging. I'm just scraping all issues from your repository and will give you some more information about this in a few minutes or so.

Because of the rate limit we can't scrape all information (including all comments and authors) right now - our system is already set up to scrape this in the next days over which the predictions will become more precise every day.

If you want me to use a different account for triaging your issues, simply create one and log in with it.

Sit tight!

Does anyone have the same problem?

Finally I chose asyncio.locks to solve the problem.

If you don't need read-write lock but just a lock -- builtin asyncio primitive works perfectly fine.

I don't understand how async with rwlock.writer doesn't release a lock though.

If you don't need read-write lock but just a lock -- builtin asyncio primitive works perfectly fine.

I don't understand how async with rwlock.writer doesn't release a lock though.

When I test the write lock in aiorwlock, when the concurrency is high, multiple coroutines will get the lock at the same time.

Do you have a test to reproduce the problem?

Do you have a test to reproduce the problem?

There are test examples, I will sort out the submission to github tomorrow.

Thanks!

Thanks!

I have submitted the test code
https://github.com/pythonsite/test_aiorwlock

Could you pin down your code to a small single file?
I believe database access is not needed for reproducing aiorwlock problems.

Could you pin down your code to a small single file?
I believe database access is not needed for reproducing aiorwlock problems.

ok! I will change the test code at night.

Sounds good!

Sounds good!

I am very sorry, I have written a few test codes and have not reproduced the problem. I will look at the problem later, and if I find out, I will send you an email.

No problem.
I've reviewed the library code again and didn't find any suspicious line.
It doesn't mean the library is buggy-less though.
If you'll come up with failed simple enough test code for a bug reproducng -- you are welcome.

Hello,
I was able to reproduce this issue with the following code:

import asyncio
import aiorwlock


async def reader(lock: aiorwlock.RWLock):
    async with lock.reader:
        pass


async def main():
    lock = aiorwlock.RWLock(fast=False)
    task_obj = asyncio.create_task(reader(lock))
    await asyncio.sleep(0)
    task_obj.cancel()
    try:
        await task_obj
    except asyncio.CancelledError:
        pass
    assert not lock.reader.locked


asyncio.run(main())

It happens because we increase _r_state inside __aenter__ and then yield before exiting __aenter__:

self._r_state += 1
self._owning.append((me, self._RL))
if self._do_yield:
await asyncio.sleep(0.0, loop=self._loop)
return True

The workaround is to set fast=True.