-
Notifications
You must be signed in to change notification settings - Fork 5
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 problems with the node cache #441
Merged
Merged
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -122,6 +122,7 @@ | |
"Doctest", | ||
"Doctests", | ||
"linenums", | ||
"XLYOFNOQVPJJNP" | ||
"XLYOFNOQVPJJNP", | ||
"CRIPTUUID" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,9 @@ | ||
from cript.nodes.exceptions import ( | ||
CRIPTOrphanedComputationalProcessError, | ||
CRIPTOrphanedComputationError, | ||
CRIPTOrphanedDataError, | ||
CRIPTOrphanedMaterialError, | ||
CRIPTOrphanedProcessError, | ||
) | ||
from cript.nodes.primary_nodes.experiment import Experiment | ||
from cript.nodes.primary_nodes.project import Project | ||
|
||
# trunk-ignore-begin(ruff/F401) | ||
from .core import ( | ||
add_orphaned_nodes_to_project, | ||
get_orphaned_experiment_exception, | ||
get_uuid_from_uid, | ||
) | ||
from .json import NodeEncoder, load_nodes_from_json | ||
|
||
# trunk-ignore-end(ruff/F401) | ||
|
||
|
||
def add_orphaned_nodes_to_project(project: Project, active_experiment: Experiment, max_iteration: int = -1): | ||
""" | ||
Helper function that adds all orphaned material nodes of the project graph to the | ||
`project.materials` attribute. | ||
Material additions only is permissible with `active_experiment is None`. | ||
This function also adds all orphaned data, process, computation and computational process nodes | ||
of the project graph to the `active_experiment`. | ||
This functions call `project.validate` and might raise Exceptions from there. | ||
""" | ||
if active_experiment is not None and active_experiment not in project.find_children({"node": ["Experiment"]}): | ||
raise RuntimeError(f"The provided active experiment {active_experiment} is not part of the project graph. Choose an active experiment that is part of a collection of this project.") | ||
|
||
counter = 0 | ||
while True: | ||
if counter > max_iteration >= 0: | ||
break # Emergency stop | ||
try: | ||
project.validate() | ||
except CRIPTOrphanedMaterialError as exc: | ||
# because calling the setter calls `validate` we have to force add the material. | ||
project._json_attrs.material.append(exc.orphaned_node) | ||
except CRIPTOrphanedDataError as exc: | ||
active_experiment.data += [exc.orphaned_node] | ||
except CRIPTOrphanedProcessError as exc: | ||
active_experiment.process += [exc.orphaned_node] | ||
except CRIPTOrphanedComputationError as exc: | ||
active_experiment.computation += [exc.orphaned_node] | ||
except CRIPTOrphanedComputationalProcessError as exc: | ||
active_experiment.computation_process += [exc.orphaned_node] | ||
else: | ||
break | ||
counter += 1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import uuid | ||
|
||
from cript.nodes.exceptions import ( | ||
CRIPTOrphanedComputationalProcessError, | ||
CRIPTOrphanedComputationError, | ||
CRIPTOrphanedDataError, | ||
CRIPTOrphanedExperimentError, | ||
CRIPTOrphanedMaterialError, | ||
CRIPTOrphanedProcessError, | ||
) | ||
|
||
|
||
def get_uuid_from_uid(uid): | ||
return str(uuid.UUID(uid[2:])) | ||
|
||
|
||
def add_orphaned_nodes_to_project(project, active_experiment, max_iteration: int = -1): | ||
""" | ||
Helper function that adds all orphaned material nodes of the project graph to the | ||
`project.materials` attribute. | ||
Material additions only is permissible with `active_experiment is None`. | ||
This function also adds all orphaned data, process, computation and computational process nodes | ||
of the project graph to the `active_experiment`. | ||
This functions call `project.validate` and might raise Exceptions from there. | ||
""" | ||
if active_experiment is not None and active_experiment not in project.find_children({"node": ["Experiment"]}): | ||
raise RuntimeError(f"The provided active experiment {active_experiment} is not part of the project graph. Choose an active experiment that is part of a collection of this project.") | ||
|
||
counter = 0 | ||
while True: | ||
if counter > max_iteration >= 0: | ||
break # Emergency stop | ||
try: | ||
project.validate() | ||
except CRIPTOrphanedMaterialError as exc: | ||
# because calling the setter calls `validate` we have to force add the material. | ||
project._json_attrs.material.append(exc.orphaned_node) | ||
except CRIPTOrphanedDataError as exc: | ||
active_experiment.data += [exc.orphaned_node] | ||
except CRIPTOrphanedProcessError as exc: | ||
active_experiment.process += [exc.orphaned_node] | ||
except CRIPTOrphanedComputationError as exc: | ||
active_experiment.computation += [exc.orphaned_node] | ||
except CRIPTOrphanedComputationalProcessError as exc: | ||
active_experiment.computation_process += [exc.orphaned_node] | ||
else: | ||
break | ||
counter += 1 | ||
|
||
|
||
def get_orphaned_experiment_exception(orphaned_node): | ||
""" | ||
Return the correct specific Exception based in the orphaned node type for nodes not correctly listed in experiment. | ||
""" | ||
from cript.nodes.primary_nodes.computation import Computation | ||
from cript.nodes.primary_nodes.computation_process import ComputationProcess | ||
from cript.nodes.primary_nodes.data import Data | ||
from cript.nodes.primary_nodes.process import Process | ||
|
||
if isinstance(orphaned_node, Data): | ||
return CRIPTOrphanedDataError(orphaned_node) | ||
if isinstance(orphaned_node, Process): | ||
return CRIPTOrphanedProcessError(orphaned_node) | ||
if isinstance(orphaned_node, Computation): | ||
return CRIPTOrphanedComputationError(orphaned_node) | ||
if isinstance(orphaned_node, ComputationProcess): | ||
return CRIPTOrphanedComputationalProcessError(orphaned_node) | ||
# Base case raise the parent exception. TODO add bug warning. | ||
return CRIPTOrphanedExperimentError(orphaned_node) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,13 +1,10 @@ | ||
import uuid | ||
from abc import ABC | ||
from dataclasses import dataclass, field, replace | ||
from typing import Any, Dict | ||
from typing import Any, Dict, Optional | ||
|
||
from cript.nodes.core import BaseNode | ||
|
||
|
||
def get_uuid_from_uid(uid): | ||
return str(uuid.UUID(uid[2:])) | ||
from cript.nodes.exceptions import CRIPTUUIDException | ||
|
||
|
||
class UUIDBaseNode(BaseNode, ABC): | ||
|
@@ -32,16 +29,26 @@ class JsonAttributes(BaseNode.JsonAttributes): | |
|
||
_json_attrs: JsonAttributes = JsonAttributes() | ||
|
||
def __new__(cls, *args, **kwargs): | ||
uuid: Optional[str] = kwargs.get("uuid") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this fixes the bug that we had before. Fun playing with something new like the |
||
if uuid and uuid in UUIDBaseNode._uuid_cache: | ||
existing_node_to_overwrite = UUIDBaseNode._uuid_cache[uuid] | ||
if type(existing_node_to_overwrite) is not cls: | ||
raise CRIPTUUIDException(uuid, type(existing_node_to_overwrite), cls) | ||
return existing_node_to_overwrite | ||
new_uuid_node = super().__new__(cls) | ||
return new_uuid_node | ||
|
||
def __init__(self, **kwargs): | ||
from cript.nodes.util.core import get_uuid_from_uid | ||
|
||
# initialize Base class with node | ||
super().__init__(**kwargs) | ||
# Respect uuid if passed as argument, otherwise construct uuid from uid | ||
uuid = kwargs.get("uuid", get_uuid_from_uid(self.uid)) | ||
uuid: str = kwargs.get("uuid", get_uuid_from_uid(self.uid)) | ||
# replace name and notes within PrimaryBase | ||
self._json_attrs = replace(self._json_attrs, uuid=uuid) | ||
|
||
# Place successfully created node in the UUID cache | ||
self._uuid_cache[uuid] = self | ||
UUIDBaseNode._uuid_cache[uuid] = self | ||
|
||
@property | ||
def uuid(self) -> uuid.UUID: | ||
|
@@ -54,11 +61,6 @@ def url(self): | |
api = _get_global_cached_api() | ||
return f"{api.host}/{api.api_prefix}/{api.api_version}/{self.uuid}" | ||
|
||
def __deepcopy__(self, memo): | ||
node = super().__deepcopy__(memo) | ||
node._json_attrs = replace(node._json_attrs, uuid=get_uuid_from_uid(node.uid)) | ||
return node | ||
|
||
@property | ||
def updated_by(self): | ||
return self._json_attrs.updated_by | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💟