Skip to content

Commit 584feac

Browse files
committed
Add cache delete in triggers and move delete_cache() to schema_manager
1 parent 68a12cb commit 584feac

File tree

3 files changed

+107
-30
lines changed

3 files changed

+107
-30
lines changed

src/app.py

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4513,7 +4513,7 @@ def require_json(request):
45134513
The HuBMAP ID (e.g. HBM123.ABCD.456) or UUID of target entity (Donor/Dataset/Sample/Upload/Collection/Publication)
45144514
"""
45154515
def delete_cache(id):
4516-
if MEMCACHED_MODE and memcached_client_instance and MEMCACHED_PREFIX:
4516+
if MEMCACHED_MODE:
45174517
# First delete the target entity cache
45184518
entity_dict = query_target_entity(id, get_internal_token())
45194519
entity_uuid = entity_dict['uuid']
@@ -4535,15 +4535,8 @@ def delete_cache(id):
45354535
upload_dict = schema_neo4j_queries.get_dataset_upload(neo4j_driver_instance, entity_uuid)
45364536

45374537
# We only use uuid in the cache key acorss all the cache types
4538-
cache_keys = []
4539-
for uuid in ([entity_uuid] + child_uuids + collection_dataset_uuids + upload_dataset_uuids + collection_uuids + [collection_dict['uuid']] + [upload_dict['uuid']]):
4540-
cache_keys.append(f'{MEMCACHED_PREFIX}_neo4j_{uuid}')
4541-
cache_keys.append(f'{MEMCACHED_PREFIX}_complete_{uuid}')
4542-
cache_keys.append(f'{MEMCACHED_PREFIX}_normalized_{uuid}')
4543-
4544-
memcached_client_instance.delete_many(cache_keys)
4545-
4546-
logger.info(f"Deleted cache by key: {', '.join(cache_keys)}")
4538+
uuids_list = [entity_uuid] + child_uuids + collection_dataset_uuids + upload_dataset_uuids + collection_uuids + [collection_dict['uuid']] + [upload_dict['uuid']]
4539+
schema_manager.delete_memcached_cache(uuids_list)
45474540

45484541

45494542
"""

src/schema/schema_manager.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1640,6 +1640,34 @@ def get_neo4j_driver_instance():
16401640
return _neo4j_driver
16411641

16421642

1643+
"""
1644+
Get the Memcached client instance to be used by trigger methods
1645+
1646+
Returns
1647+
-------
1648+
neo4j.Driver
1649+
The neo4j.Driver instance
1650+
"""
1651+
def get_memcached_client_instance():
1652+
global _memcached_client
1653+
1654+
return _memcached_client
1655+
1656+
1657+
"""
1658+
Get the configured Memcached prefix to be used by trigger methods
1659+
1660+
Returns
1661+
-------
1662+
neo4j.Driver
1663+
The neo4j.Driver instance
1664+
"""
1665+
def get_memcached_prefix():
1666+
global _memcached_prefix
1667+
1668+
return _memcached_prefix
1669+
1670+
16431671
"""
16441672
Convert a string representation of the Python list/dict (either nested or not) to a Python list/dict object
16451673
with removing any non-printable control characters if presents.
@@ -1737,6 +1765,30 @@ def make_request_get(target_url, internal_token_used = False):
17371765
return response
17381766

17391767

1768+
"""
1769+
Delete the cached data for the given entity uuids
1770+
1771+
Parameters
1772+
----------
1773+
uuids_list : list
1774+
A list of target uuids
1775+
"""
1776+
def delete_memcached_cache(uuids_list):
1777+
global _memcached_client
1778+
global _memcached_prefix
1779+
1780+
if _memcached_client and _memcached_prefix:
1781+
cache_keys = []
1782+
for uuid in uuids_list:
1783+
cache_keys.append(f'{_memcached_prefix}_neo4j_{uuid}')
1784+
cache_keys.append(f'{_memcached_prefix}_complete_{uuid}')
1785+
cache_keys.append(f'{_memcached_prefix}_normalized_{uuid}')
1786+
1787+
_memcached_client.delete_many(cache_keys)
1788+
1789+
logger.info(f"Deleted cache by key: {', '.join(cache_keys)}")
1790+
1791+
17401792
####################################################################################################
17411793
## Internal functions
17421794
####################################################################################################

src/schema/schema_triggers.py

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -807,11 +807,6 @@ def get_dataset_upload(property_key, normalized_type, user_token, existing_data_
807807
A dictionary that contains all existing entity properties
808808
new_data_dict : dict
809809
A merged dictionary that contains all possible input data to be used
810-
811-
Returns
812-
-------
813-
str: The target property key
814-
str: The uuid string of source entity
815810
"""
816811
def link_dataset_to_direct_ancestors(property_key, normalized_type, user_token, existing_data_dict, new_data_dict):
817812
if 'uuid' not in existing_data_dict:
@@ -820,14 +815,19 @@ def link_dataset_to_direct_ancestors(property_key, normalized_type, user_token,
820815
if 'direct_ancestor_uuids' not in existing_data_dict:
821816
raise KeyError("Missing 'direct_ancestor_uuids' key in 'existing_data_dict' during calling 'link_dataset_to_direct_ancestors()' trigger method.")
822817

818+
dataset_uuid = existing_data_dict['uuid']
823819
direct_ancestor_uuids = existing_data_dict['direct_ancestor_uuids']
824820

825821
# Generate property values for Activity node
826822
activity_data_dict = schema_manager.generate_activity_data(normalized_type, user_token, existing_data_dict)
827823

828824
try:
829825
# Create a linkage (via one Activity node) between the dataset node and its direct ancestors in neo4j
830-
schema_neo4j_queries.link_entity_to_direct_ancestors(schema_manager.get_neo4j_driver_instance(), existing_data_dict['uuid'], direct_ancestor_uuids, activity_data_dict)
826+
schema_neo4j_queries.link_entity_to_direct_ancestors(schema_manager.get_neo4j_driver_instance(), dataset_uuid, direct_ancestor_uuids, activity_data_dict)
827+
828+
# Delete the cache of this dataset if any cache exists
829+
# Because the `Dataset.direct_ancestors` field
830+
schema_manager.delete_memcached_cache([dataset_uuid])
831831
except TransactionError:
832832
# No need to log
833833
raise
@@ -847,11 +847,6 @@ def link_dataset_to_direct_ancestors(property_key, normalized_type, user_token,
847847
A dictionary that contains all existing entity properties
848848
new_data_dict : dict
849849
A merged dictionary that contains all possible input data to be used
850-
851-
Returns
852-
-------
853-
str: The target property key
854-
str: The uuid string of source entity
855850
"""
856851
def link_collection_to_datasets(property_key, normalized_type, user_token, existing_data_dict, new_data_dict):
857852
if 'uuid' not in existing_data_dict:
@@ -860,13 +855,19 @@ def link_collection_to_datasets(property_key, normalized_type, user_token, exist
860855
if 'dataset_uuids' not in existing_data_dict:
861856
raise KeyError("Missing 'dataset_uuids' key in 'existing_data_dict' during calling 'link_collection_to_datasets()' trigger method.")
862857

858+
collection_uuid = existing_data_dict['uuid']
863859
dataset_uuids = existing_data_dict['dataset_uuids']
864860

865861
try:
866862
# Create a linkage (without an Activity node) between the Collection node and each Dataset it contains.
867863
schema_neo4j_queries.link_collection_to_datasets(neo4j_driver=schema_manager.get_neo4j_driver_instance()
868864
,collection_uuid=existing_data_dict['uuid']
869865
,dataset_uuid_list=dataset_uuids)
866+
867+
# Delete the cache of each associated dataset and the collection itself if any cache exists
868+
# Because the `Dataset.collecctions` field and `Collection.datasets` field
869+
uuids_list = [collection_uuid] + dataset_uuids
870+
schema_manager.delete_memcached_cache(uuids_list)
870871
except TransactionError as te:
871872
# No need to log
872873
raise
@@ -976,11 +977,6 @@ def get_local_directory_rel_path(property_key, normalized_type, user_token, exis
976977
A dictionary that contains all existing entity properties
977978
new_data_dict : dict
978979
A merged dictionary that contains all possible input data to be used
979-
980-
Returns
981-
-------
982-
str: The target property key
983-
str: The uuid string of source entity
984980
"""
985981
def link_to_previous_revision(property_key, normalized_type, user_token, existing_data_dict, new_data_dict):
986982
if 'uuid' not in existing_data_dict:
@@ -989,9 +985,17 @@ def link_to_previous_revision(property_key, normalized_type, user_token, existin
989985
if 'previous_revision_uuid' not in existing_data_dict:
990986
raise KeyError("Missing 'previous_revision_uuid' key in 'existing_data_dict' during calling 'link_to_previous_revision()' trigger method.")
991987

988+
entity_uuid = existing_data_dict['uuid']
989+
previous_uuid = existing_data_dict['previous_revision_uuid']
990+
992991
# Create a revision reltionship from this new Dataset node and its previous revision of dataset node in neo4j
993992
try:
994-
schema_neo4j_queries.link_entity_to_previous_revision(schema_manager.get_neo4j_driver_instance(), existing_data_dict['uuid'], existing_data_dict['previous_revision_uuid'])
993+
schema_neo4j_queries.link_entity_to_previous_revision(schema_manager.get_neo4j_driver_instance(), entity_uuid, previous_uuid)
994+
995+
# Delete the cache of each associated dataset if any cache exists
996+
# Because the `Dataset.previous_revision_uuid` and `Dataset.next_revision_uuid` fields
997+
uuids_list = [entity_uuid, previous_uuid]
998+
schema_manager.delete_memcached_cache(uuids_list)
995999
except TransactionError:
9961000
# No need to log
9971001
raise
@@ -1392,6 +1396,8 @@ def link_donor_to_lab(property_key, normalized_type, user_token, existing_data_d
13921396
# Create a linkage (via Activity node)
13931397
# between the Donor node and the parent Lab node in neo4j
13941398
schema_neo4j_queries.link_entity_to_direct_ancestors(schema_manager.get_neo4j_driver_instance(), existing_data_dict['uuid'], direct_ancestor_uuids, activity_data_dict)
1399+
1400+
# No need to delete any cache here since this is one-time donor creation
13951401
except TransactionError:
13961402
# No need to log
13971403
raise
@@ -1507,6 +1513,8 @@ def link_sample_to_direct_ancestor(property_key, normalized_type, user_token, ex
15071513
if 'direct_ancestor_uuid' not in existing_data_dict:
15081514
raise KeyError("Missing 'direct_ancestor_uuid' key in 'existing_data_dict' during calling 'link_sample_to_direct_ancestor()' trigger method.")
15091515

1516+
sample_uuid = existing_data_dict['uuid']
1517+
15101518
# Build a list of direct ancestor uuids
15111519
# Only one uuid in the list in this case
15121520
direct_ancestor_uuids = [existing_data_dict['direct_ancestor_uuid']]
@@ -1517,7 +1525,11 @@ def link_sample_to_direct_ancestor(property_key, normalized_type, user_token, ex
15171525
try:
15181526
# Create a linkage (via Activity node)
15191527
# between the Sample node and the source entity node in neo4j
1520-
schema_neo4j_queries.link_entity_to_direct_ancestors(schema_manager.get_neo4j_driver_instance(), existing_data_dict['uuid'], direct_ancestor_uuids, activity_data_dict)
1528+
schema_neo4j_queries.link_entity_to_direct_ancestors(schema_manager.get_neo4j_driver_instance(), sample_uuid, direct_ancestor_uuids, activity_data_dict)
1529+
1530+
# Delete the cache of sample if any cache exists
1531+
# Because the `Sample.direct_ancestor` field can be updated
1532+
schema_manager.delete_memcached_cache([sample_uuid])
15211533
except TransactionError:
15221534
# No need to log
15231535
raise
@@ -1553,6 +1565,8 @@ def link_publication_to_associated_collection(property_key, normalized_type, use
15531565
# Create a linkage
15541566
# between the Publication node and the Collection node in neo4j
15551567
schema_neo4j_queries.link_publication_to_associated_collection(schema_manager.get_neo4j_driver_instance(), existing_data_dict['uuid'], associated_collection_uuid)
1568+
1569+
# Will need to delete the collection cache if later we add `Collection.associated_publications` field - 7/16/2023 Zhou
15561570
except TransactionError:
15571571
# No need to log
15581572
raise
@@ -1791,6 +1805,8 @@ def link_upload_to_lab(property_key, normalized_type, user_token, existing_data_
17911805
# Create a linkage (via Activity node)
17921806
# between the Submission node and the parent Lab node in neo4j
17931807
schema_neo4j_queries.link_entity_to_direct_ancestors(schema_manager.get_neo4j_driver_instance(), existing_data_dict['uuid'], direct_ancestor_uuids, activity_data_dict)
1808+
1809+
# No need to delete any cache here since this is one-time upload creation
17941810
except TransactionError:
17951811
# No need to log
17961812
raise
@@ -1818,9 +1834,17 @@ def link_datasets_to_upload(property_key, normalized_type, user_token, existing_
18181834
if 'dataset_uuids_to_link' not in existing_data_dict:
18191835
raise KeyError("Missing 'dataset_uuids_to_link' key in 'existing_data_dict' during calling 'link_datasets_to_upload()' trigger method.")
18201836

1837+
upload_uuid = existing_data_dict['uuid']
1838+
dataset_uuids = existing_data_dict['dataset_uuids_to_link']
1839+
18211840
try:
18221841
# Create a direct linkage (Dataset) - [:IN_UPLOAD] -> (Submission) for each dataset
1823-
schema_neo4j_queries.link_datasets_to_upload(schema_manager.get_neo4j_driver_instance(), existing_data_dict['uuid'], existing_data_dict['dataset_uuids_to_link'])
1842+
schema_neo4j_queries.link_datasets_to_upload(schema_manager.get_neo4j_driver_instance(), upload_uuid, dataset_uuids)
1843+
1844+
# Delete the cache of each associated dataset and the target upload if any cache exists
1845+
# Because the `Dataset.upload` and `Upload.datasets` fields, and
1846+
uuids_list = [upload_uuid] + dataset_uuids
1847+
schema_manager.delete_memcached_cache(uuids_list)
18241848
except TransactionError:
18251849
# No need to log
18261850
raise
@@ -1849,9 +1873,17 @@ def unlink_datasets_from_upload(property_key, normalized_type, user_token, exist
18491873
if 'dataset_uuids_to_unlink' not in existing_data_dict:
18501874
raise KeyError("Missing 'dataset_uuids_to_unlink' key in 'existing_data_dict' during calling 'unlink_datasets_from_upload()' trigger method.")
18511875

1876+
upload_uuid = existing_data_dict['uuid']
1877+
dataset_uuids = existing_data_dict['dataset_uuids_to_unlink']
1878+
18521879
try:
18531880
# Delete the linkage (Dataset) - [:IN_UPLOAD] -> (Upload) for each dataset
1854-
schema_neo4j_queries.unlink_datasets_from_upload(schema_manager.get_neo4j_driver_instance(), existing_data_dict['uuid'], existing_data_dict['dataset_uuids_to_unlink'])
1881+
schema_neo4j_queries.unlink_datasets_from_upload(schema_manager.get_neo4j_driver_instance(), upload_uuid, dataset_uuids)
1882+
1883+
# Delete the cache of each associated dataset and the upload itself if any cache exists
1884+
# Because the associated datasets have this `Dataset.upload` field and Upload has `Upload.datasets` field
1885+
uuids_list = dataset_uuids + [upload_uuid]
1886+
schema_manager.delete_memcached_cache(uuids_list)
18551887
except TransactionError:
18561888
# No need to log
18571889
raise

0 commit comments

Comments
 (0)