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/remove create array lock #47

Merged
merged 4 commits into from
May 8, 2024
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
2 changes: 1 addition & 1 deletion .github/workflows/on_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ jobs:
url: https://pypi.org/p/${{ vars.PACKAGE_NAME }}

steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
# unpacks default artifact into dist/
# if `name: artifact` is omitted, the action will create extra parent dir
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/on_test_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
url: https://test.pypi.org/p/${{ vars.PACKAGE_NAME }}

steps:
- uses: actions/download-artifact@v3
- uses: actions/download-artifact@v4
with:
# unpacks default artifact into dist/
# if `name: artifact` is omitted, the action will create extra parent dir
Expand Down
74 changes: 0 additions & 74 deletions deker/locks.py
Original file line number Diff line number Diff line change
Expand Up @@ -417,80 +417,6 @@ def _inner_method_logic(
return super()._inner_method_logic(lock, args, kwargs, func)


class CreateArrayLock(LockWithArrayMixin[Union["Array", "VArray", dict]], BaseLock):
"""Lock that we set when we want to create an array."""

ALLOWED_TYPES = ["LocalArrayAdapter", "LocalVArrayAdapter"]

path: Optional[Path] = None

def get_path(self) -> Path:
"""Return path to the file that should be locked."""
# Get file directory path
dir_path = self.instance.collection_path

# Create lock file
path = dir_path / _get_lock_filename(self.array.id, LocksExtensions.array_lock)
if not path.exists():
path.open("w").close()

self.path = path
self.logger.debug(f"got path for array.id {self.array.id} lock file: {path}")
return path

def check_existing_lock(self, func_args: Sequence, func_kwargs: Dict) -> None:
"""Check if there is currently lock for array creating.

:param func_args: arguments for called method
:param func_kwargs: keyword arguments for called method
"""
from deker.arrays import Array, VArray

array = self.array
# Check current read locks
if isinstance(array, dict):
adapter = array["adapter"].__class__.__name__
if adapter not in self.ALLOWED_TYPES:
raise DekerLockError(f"Adapter {adapter} is not allowed to create locks for arrays")

# TODO: figure out a way to avoid constructing Array object here
array_type = Array if adapter == self.ALLOWED_TYPES[0] else VArray
array = array_type(**array)

dir_path = self.instance.collection_path

# Pattern that has to find any create locks
glob_pattern = f"{array.id}:*{LocksExtensions.array_lock.value}"
for _ in dir_path.rglob(glob_pattern):
raise DekerLockError(f"Array {array.id} is locked for creating")

func_kwargs["array"] = array

def get_result(self, func: Callable, args: Any, kwargs: Any) -> Any:
"""Call func, and get its result.

:param func: decorated function
:param args: arguments of decorated function
:param kwargs: keyword arguments of decorated function
"""
if kw_array := kwargs.pop("array"):
args = list(args)
# First elem is self, so for functions with array, set array as next arg.
args[1] = kw_array
result = func(*tuple(args), **kwargs)
else:
result = func(*args, **kwargs)
return result

def release(self, e: Optional[Exception] = None) -> None:
"""Release Flock.

:param e: exception that might have been raised
"""
self.path.unlink(missing_ok=True)
super().release(e)


class UpdateMetaAttributeLock(LockWithArrayMixin[Union["Array", "VArray"]], BaseLock):
"""Lock for updating meta."""

Expand Down
4 changes: 3 additions & 1 deletion deker/managers.py
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,11 @@ def _create( # type: ignore
"array_adapter": self.__array_adapter, # type: ignore[dict-item]
}
)
array = VArray(**arr_params) # type: ignore[arg-type]
else:
arr_params.update({"adapter": self.__array_adapter}) # type: ignore[dict-item]
array = self._adapter.create(arr_params)
array = Array(**arr_params) # type: ignore[arg-type]
self._adapter.create(array)
return array

def create(
Expand Down
23 changes: 12 additions & 11 deletions deker/subset.py
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ def update(self, data: Data) -> None:

:param data: new data which shall match subset slicing
"""
from deker.arrays import Array

def _update(array_data: ArrayPositionedData) -> None:
"""If there is a need in the future to calculate Array's time dimension start value. # noqa: DAR101, D400
Expand All @@ -600,17 +601,17 @@ def _update(array_data: ArrayPositionedData) -> None:
pos = array_data.vposition[n]
custom_attributes[attr_name] = dim.start_value + dim.step * pos # type: ignore[operator]

array = self.__array_adapter.create(
{
"collection": self.__collection,
"adapter": self.__array_adapter,
"primary_attributes": {
"vid": self.__array.id,
"v_position": array_data.vposition,
},
"custom_attributes": custom_attributes,
}
)
kwargs = {
"collection": self.__collection,
"adapter": self.__array_adapter,
"primary_attributes": {
"vid": self.__array.id,
"v_position": array_data.vposition,
},
"custom_attributes": custom_attributes,
}
array = Array(**kwargs) # type: ignore[arg-type]
self.__array_adapter.create(array)
subset = array[array_data.bounds]
subset.update(array_data.data)

Expand Down
Loading
Loading