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

Fix race condition during Python library loading #350

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 6 additions & 3 deletions wrappers/python/aries_askar/bindings/lib.py
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,7 @@ def __new__(cls, *args):
inst = cls.INSTANCE and cls.INSTANCE()
if inst is None:
inst = super().__new__(cls, *args)
inst._initlock = threading.Lock()
inst._lib = None
inst._objs = []
# Keep a weak reference to the instance. This assumes that
Expand All @@ -351,10 +352,12 @@ def __new__(cls, *args):

@property
def loaded(self) -> LibLoad:
"""Determine if the library has been loaded."""
"""Access the loaded library instance, initializing it if necessary."""
if not self._lib:
self._lib = LibLoad(self.__class__.LIB_NAME)
self._objs.append(self._lib)
with self._initlock:
if not self._lib:
self._lib = LibLoad(self.__class__.LIB_NAME)
self._objs.append(self._lib)
return self._lib

def invoke(self, name, argtypes, *args):
Expand Down
31 changes: 20 additions & 11 deletions wrappers/python/aries_askar/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@
except ImportError:
import json

from functools import lru_cache
from typing import Optional, Sequence, Union

from cached_property import cached_property

from . import bindings
from .bindings import (
EntryListHandle,
Expand All @@ -32,22 +31,26 @@ def __init__(self, lst: EntryListHandle, pos: int):
self._list = lst
self._pos = pos

@cached_property
@property
@lru_cache(maxsize=None)
def category(self) -> str:
"""Accessor for the entry category."""
return self._list.get_category(self._pos)

@cached_property
@property
@lru_cache(maxsize=None)
def name(self) -> str:
"""Accessor for the entry name."""
return self._list.get_name(self._pos)

@property
@lru_cache(maxsize=None)
def value(self) -> bytes:
"""Accessor for the entry value."""
return bytes(self.raw_value)

@cached_property
@property
@lru_cache(maxsize=None)
def raw_value(self) -> memoryview:
"""Accessor for the entry raw value."""
return self._list.get_value(self._pos)
Expand All @@ -57,7 +60,8 @@ def value_json(self) -> dict:
"""Accessor for the entry value as JSON."""
return json.loads(self.value)

@cached_property
@property
@lru_cache(maxsize=None)
def tags(self) -> dict:
"""Accessor for the entry tags."""
return self._list.get_tags(self._pos)
Expand Down Expand Up @@ -147,27 +151,32 @@ def __init__(self, lst: KeyEntryListHandle, pos: int):
self._list = lst
self._pos = pos

@cached_property
@property
@lru_cache(maxsize=None)
def algorithm(self) -> str:
"""Accessor for the key entry algorithm."""
return self._list.get_algorithm(self._pos)

@cached_property
@property
@lru_cache(maxsize=None)
def name(self) -> str:
"""Accessor for the key entry name."""
return self._list.get_name(self._pos)

@cached_property
@property
@lru_cache(maxsize=None)
def metadata(self) -> str:
"""Accessor for the key entry metadata."""
return self._list.get_metadata(self._pos)

@cached_property
@property
@lru_cache(maxsize=None)
def key(self) -> Key:
"""Accessor for the entry metadata."""
return Key(self._list.load_key(self._pos))

@cached_property
@property
@lru_cache(maxsize=None)
def tags(self) -> dict:
"""Accessor for the entry tags."""
return self._list.get_tags(self._pos)
Expand Down
1 change: 0 additions & 1 deletion wrappers/python/requirements.txt
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
cached_property~=2.0.0
Loading