Skip to content
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

[jarun#753] implement thread safety #760

Merged
merged 1 commit into from
Aug 24, 2024
Merged

Conversation

LeXofLeviafan
Copy link
Collaborator

…So I've been working on Bootstrap v4 migration (…as much as my free time permitted), and encountered a bug that caused every new modal to send twice as many fetch requests as the previous one when being opened. This exposed a problem in the main Buku library: it's not threadsafe. (More specifically, dealing with two simultaneous web-requests causes an error, and having more than that results in an immediate segfault.)

Hence, I've added a repeating-lock to handle concurrent access (it doesn't interfere with same-thread actions, thus only affecting the cases when the library is used from multiple threads at once), and published it as a separate pull-request.

I've made sure it doesn't cause issues with concurrent access, but just in case I've also added a 10 seconds time limit on execution of each test (to handle possible deadlocks).

self.cur.execute(query, args)
return [BookmarkVar(*x) for x in self.cur.fetchall()]
with self.lock:
return self._fetch(query, *args, lock=False)
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change only affects concurrent access (which would throw an error before the fix)

self.cur.execute(query, list(indices))
resultset = self.cur.fetchall()
if not resultset:
return False
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the short branch from below

@@ -909,8 +943,6 @@ class BukuDb:

if not delay_commit:
self.conn.commit()
else:
return False
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved the branch to above

@@ -1231,146 +1265,139 @@ class BukuDb:
if not MYHEADERS:
gen_headers()

cond = threading.Condition()
cond.acquire()
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this below

count : int
Dummy input to adhere to convention.
thread_idx : int
Thread index/ID.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can be used for logging etc.

cond : threading condition object.
"""

count = 0
_count = 0
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensuring it's a local variable

if resultset:
id, url, tags, flags = resultset.pop()
else:
break
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not actually changing any behaviour here, but using with does away with explicit .release()

@@ -1,4 +1,6 @@
[pytest]
timeout = 10
timeout_method = thread
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensuring the tests won't freeze in case of a deadlock 😅

Note that default timeout-method is signal, but it doesn't appear to handle deadlocks well.

@jarun jarun merged commit fe9b9d9 into jarun:master Aug 24, 2024
1 check passed
@jarun
Copy link
Owner

jarun commented Aug 24, 2024

Thank you!

@LeXofLeviafan LeXofLeviafan deleted the threadsafe branch August 24, 2024 17:44
@github-actions github-actions bot locked and limited conversation to collaborators Jan 12, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants