Skip to content

Ensure <connection object>:execute() don't block a fiber infinitely #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Totktonada opened this issue Nov 22, 2019 · 0 comments · Fixed by #55
Closed

Ensure <connection object>:execute() don't block a fiber infinitely #34

Totktonada opened this issue Nov 22, 2019 · 0 comments · Fixed by #55
Assignees
Labels
bug Something isn't working

Comments

@Totktonada
Copy link
Member

Case: a connection is acquired from a pool, then three fibers use it: one calls <connection object>:execute() and acquires a lock (let's consider a long request), another one perform other calls to :execute() and third one put the connection back to the pool.

Say, when the long request will be done, the third fiber will acquire the lock and put the connection to the pool. The old connection object will be marked as unusable, however the lock will not be released (see conn_put). The second fiber will be blocked infinitely.

Even if we'll release the lock in <pool object>:put() and the second fiber will wake up in :execute(), it will at the point after self.usable check and will try to execute a request. It will even succeed, but it looks as a side effect of #32.

It is maybe not quite correct usage, but we should handle it appropriately: wait for necessary events, give an error for an incorrect usage, don't leak resources and surely don't block a fiber infinitely.

It seems the similar problem with passed <connection object>.usable check may appears for a connection that is created with mysql.connect() w/o a pool if we'll try the similar case, but with <connection object>:close() instead of <pool object>:put().

NB: Add test cases for both described situations.

@Totktonada Totktonada added the bug Something isn't working label Nov 22, 2019
@romanhabibov romanhabibov self-assigned this Dec 12, 2020
romanhabibov added a commit that referenced this issue Dec 17, 2020
The absence of this operation could lead to an infinite bloсking
when used with fiber (case in tests).

Closes #34
romanhabibov added a commit that referenced this issue Dec 17, 2020
The absence of this operation could lead to an infinite bloсking
when used with fiber (case in tests).

Closes #34
romanhabibov added a commit that referenced this issue Dec 17, 2020
Test that concurrent use of execute and close does not result
to infinite blocking.

Part of #34
@LeonidVas LeonidVas linked a pull request Dec 22, 2020 that will close this issue
romanhabibov added a commit that referenced this issue Dec 23, 2020
The absence of this operation could lead to an infinite bloсking
when used with fiber as describerd in the case below.

A connection `conn`is acquired from a pool, then three fibers use
it: the first one calls `conn:execute()` and acquires a lock
(let's consider a long request), another one perform other calls
to `conn:execute()` and third one put the connection back to the
pool. When the long request will be done, the third fiber will
acquire the lock and put the connection to the pool. The old
connection object will be marked as `unusable`, however the lock
will not be released (before this patch). The second fiber will be
blocked infinitely on `conn:execute()`'s `get()`.

Closes #34
romanhabibov added a commit that referenced this issue Dec 23, 2020
Test that concurrent use of execute and close does not result
to infinite blocking.

Part of #34
romanhabibov added a commit that referenced this issue Dec 23, 2020
The absence of this operation could lead to an infinite bloсking
when used with fiber as describerd in the case below.

A connection `conn`is acquired from a pool, then three fibers use
it: the first one calls `conn:execute()` and acquires a lock
(let's consider a long request), another one perform other calls
to `conn:execute()` and third one put the connection back to the
pool. When the long request will be done, the third fiber will
acquire the lock and put the connection to the pool. The old
connection object will be marked as `unusable`, however the lock
will not be released (before this patch). The second fiber will be
blocked infinitely on `conn:execute()`'s `get()`.

Closes #34
romanhabibov added a commit that referenced this issue Dec 23, 2020
Test that concurrent use of `execute` and `close` does not result
to infinite blocking.

Part of #34
romanhabibov added a commit that referenced this issue Dec 24, 2020
The absence of this operation could lead to an infinite bloсking
when used with fiber as describerd in the case below.

A connection `conn`is acquired from a pool, then three fibers use
it: the first one calls `conn:execute()` and acquires a lock
(let's consider a long request), another one perform other calls
to `conn:execute()` and third one put the connection back to the
pool. When the long request will be done, the third fiber will
acquire the lock and put the connection to the pool. The old
connection object will be marked as `unusable`, however the lock
will not be released (before this patch). The second fiber will be
blocked infinitely on `conn:execute()`'s `get()`.

Closes #34
romanhabibov added a commit that referenced this issue Dec 24, 2020
Test that concurrent use of `execute` and `close` does not result
to infinite blocking.

Part of #34
romanhabibov added a commit that referenced this issue Dec 24, 2020
The absence of this operation could lead to an infinite bloсking
when used with fiber as describerd in the case below.

A connection `conn`is acquired from a pool, then three fibers use
it: the first one calls `conn:execute()` and acquires a lock
(let's consider a long request), another one perform other calls
to `conn:execute()` and third one put the connection back to the
pool. When the long request will be done, the third fiber will
acquire the lock and put the connection to the pool. The old
connection object will be marked as `unusable`, however the lock
will not be released (before this patch). The second fiber will be
blocked infinitely on `conn:execute()`'s `get()`.

Closes #34
romanhabibov added a commit that referenced this issue Dec 24, 2020
Test that concurrent use of `execute` and `close` does not result
to infinite blocking.

Part of #34
romanhabibov added a commit that referenced this issue Dec 27, 2020
The absence of this operation could lead to an infinite bloсking
when used with fiber as describerd in the case below.

A connection conn is acquired from a pool and we acquire a lock.
Then we start the first fiber with pool:put(conn)`, which try to
acquire lock and yield. Then the second fiber is started to
perform request with `conn:execute()` which try to acquire lock,
because the connection is still marked as `usable` and yield too.
Before this patch, it's appeared that the lock is never released.

Closes #34
romanhabibov added a commit that referenced this issue Jan 13, 2021
The absence of this operation could lead to an infinite bloсking
when used with fiber as describerd in the case below.

A connection conn is acquired from a pool and we acquire a lock.
Then we start the first fiber with pool:put(conn)`, which try to
acquire lock and yield. Then the second fiber is started to
perform request with `conn:execute()` which try to acquire lock,
because the connection is still marked as `usable` and yield too.
Before this patch, it's appeared that the lock is never released.

Closes #34
romanhabibov added a commit that referenced this issue Jan 13, 2021
The absence of this operation could lead to an infinite bloсking
when used with fiber as describerd in the case below.

A connection conn is acquired from a pool and we acquire a lock.
Then we start the first fiber with pool:put(conn)`, which try to
acquire lock and yield. Then the second fiber is started to
perform request with `conn:execute()` which try to acquire lock,
because the connection is still marked as `usable` and yield too.
Before this patch, it's appeared that the lock is never released.

Closes #34
romanhabibov added a commit that referenced this issue Feb 1, 2021
The absence of this operation could lead to an infinite bloсking
when used with fiber as describerd in the case below.

A connection conn is acquired from a pool and we acquire a lock.
Then we start the first fiber with pool:put(conn)`, which try to
acquire lock and yield. Then the second fiber is started to
perform conn:execute(), conn:reset() and conn:quote() which try
to acquire lock, because the connection is still marked as
`usable` and yield too. Before this patch, it's appeared that the
lock is never released.

Closes #34
romanhabibov added a commit that referenced this issue Feb 1, 2021
Make lock arithmetic proper and complite in conn:execute(),
conn:close(), conn:reset() and conn:quote(). Release lock in
pool:put(conn). The absence of this operation could lead to an
infinite bloсking when used with fiber as describerd in the case
below.

A connection conn is acquired from a pool and we acquire a lock.
Then we start the first fiber with pool:put(conn)`, which try to
acquire lock and yield. Then the second fiber is started to
perform conn:execute(), conn:reset() and conn:quote() which try
to acquire lock, because the connection is still marked as
`usable` and yield too. Before this patch, it's appeared that the
lock is never released.

Closes #34
romanhabibov added a commit that referenced this issue Feb 26, 2021
Make lock arithmetic proper and complite in conn:execute(),
conn:close(), conn:reset() and conn:quote(). Release lock in
pool:put(conn). The absence of this operation could lead to an
infinite bloсking when used with fiber as describerd in the case
below.

A connection conn is acquired from a pool and we acquire a lock.
Then we start the first fiber with pool:put(conn)`, which try to
acquire lock and yield. Then the second fiber is started to
perform conn:execute(), conn:reset() and conn:quote() which try
to acquire lock, because the connection is still marked as
`usable` and yield too. Before this patch, it's appeared that the
lock is never released.

Closes #34
Totktonada pushed a commit that referenced this issue Mar 2, 2021
Make lock arithmetic proper and complite in conn:execute(),
conn:close(), conn:reset() and conn:quote(). Release lock in
pool:put(conn). The absence of this operation could lead to an
infinite bloсking when used with fiber as describerd in the case
below.

A connection conn is acquired from a pool and we acquire a lock.
Then we start the first fiber with pool:put(conn)`, which try to
acquire lock and yield. Then the second fiber is started to
perform conn:execute(), conn:reset() and conn:quote() which try
to acquire lock, because the connection is still marked as
`usable` and yield too. Before this patch, it's appeared that the
lock is never released.

Closes #34
Totktonada pushed a commit that referenced this issue Mar 2, 2021
Make lock arithmetic proper and complite in conn:execute(),
conn:close(), conn:reset() and conn:quote(). Release lock in
pool:put(conn). The absence of this operation could lead to an
infinite bloсking when used with fiber as describerd in the case
below.

A connection conn is acquired from a pool and we acquire a lock.
Then we start the first fiber with pool:put(conn)`, which try to
acquire lock and yield. Then the second fiber is started to
perform conn:execute(), conn:reset() and conn:quote() which try
to acquire lock, because the connection is still marked as
`usable` and yield too. Before this patch, it's appeared that the
lock is never released.

Closes #34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants