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

Refactor Catalog Indexing #2632

Merged
merged 24 commits into from
Oct 31, 2024
Merged

Refactor Catalog Indexing #2632

merged 24 commits into from
Oct 31, 2024

Conversation

ramonski
Copy link
Contributor

Description of the issue/feature this PR addresses

This PR refactors the catalog indexing by using the IndexQueue for all SENAITE catalogs and avoids multiple UID catalog indexing.

Current behavior before PR

AT object indexing never use the IndexQueue and temporary objects were indexed in UID catalog

Desired behavior after PR is merged

AT object indexing always use the IndexQueue and no temporary objects are indexed in UID catalog

--
I confirm I have tested this PR thoroughly and coded it according to PEP8
and Plone's Python styleguide standards.

@ramonski ramonski marked this pull request as ready for review October 24, 2024 11:15
@ramonski ramonski requested a review from xispa October 24, 2024 11:37
Copy link
Member

@xispa xispa left a comment

Choose a reason for hiding this comment

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

Awesome!, thanks for the doctest and README's (really useful and necessary). Have left some comments and questions

# reindex UID
uid_catalog = api.get_tool("uid_catalog")
uid_catalog.catalog_object(obj, obj._getURL())
# reindex object in all other catalogs
Copy link
Member

Choose a reason for hiding this comment

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

To not spread here and there same thing, I suggest to rely on api.catalog_object function, that already takes care of uid_catalog here: https://github.com/senaite/senaite.core/blob/2.x/src/bika/lims/api/__init__.py#L403-L417

We could even include the recursive param in api.catalog_object function as well and remove this reindex function from here. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for the hint! I already forgot that we have an API function that does this.
Changes done in c725d9d

"""Get a list of catalog IDs for the given object
"""
# get a list of catalog IDs that are mapped to the object
catalogs = list(map(lambda x: x.id, api.get_catalogs_for(obj)))
Copy link
Member

Choose a reason for hiding this comment

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

Note that by default api.get_catalogs_for relies on this static mapping to get the catalogs for a given portal type. And the value of the attribute _catalog is taken into account only when the portal type of the given object is not present in that mapping: https://github.com/senaite/senaite.core/blob/2.x/src/bika/lims/api/__init__.py#L1276

In my opinion this static mapping forces us to monkey patch api.get_catalogs_for if we want an existing baseline type (like AnalysisRequest) to also be catalogued in a brand-new-add-on-specific catalog.

So, I think this change is fine as long as we skip the static mapping check in api.get_catalogs_for. Or maybe don't skip, but rely on a new adapter to get additional catalogs for baseline portal_types.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, you are right and this is why we have the TODO in the docstring here:

def get_catalogs_by_type(portal_type):
"""Return the mapped catalogs by type
TODO: Provide registry setting for this mapping lookup
:param portal_type: The portal type to look up
"""
if not isinstance(portal_type, str):
raise TypeError("Expected string type, got <%s>" % type(portal_type))
mapping = dict(CATALOG_MAPPINGS)
catalogs = mapping.get(portal_type)
if not catalogs:
return []
return catalogs

I guess providing the mapping as a registry setting we could easily add/remove/edit catalogs from the base types and new types.

For the moment I would like to postpone that until we have this requirement and provide it in a new PR

return
if not uc:
uc = api.get_tool(UID_CATALOG)
url = self._getURL()
Copy link
Member

Choose a reason for hiding this comment

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

Note for @xispa : ._getURL() relies on Archetypes.utils.getRelPath, that returns the relative path of the object from the portal root. The result is the same as url = "/".join(obj.getPhysicalPath()[2:])

PORTAL_CATALOG = "portal_catalog"


def index_in_portal_catalog(obj):
Copy link
Member

Choose a reason for hiding this comment

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

Shouldn't we also check for api.is_temporary(obj), like what you did in catalog_multiplex?

Copy link
Contributor Author

@ramonski ramonski Oct 30, 2024

Choose a reason for hiding this comment

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

Everything that ends up in this queue comes from Products.CMFCore.CatalogTool.reindexObject which does already filterTemporaryItems, which uses our patched isTemporary for both AT and DX types:

def isTemporary(self):
return api.is_temporary(self)

def isTemporary(self):
return api.is_temporary(self)

So another api.is_temporary is at this stage not required

Copy link
Member

@xispa xispa left a comment

Choose a reason for hiding this comment

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

Excellent, thanks!

@xispa xispa merged commit a5fbfbd into 2.x Oct 31, 2024
2 checks passed
@xispa xispa deleted the rethink-catalog-indexing branch October 31, 2024 14:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Cleanup 🧹 Code cleanup and refactoring Improvement 🔧
Development

Successfully merging this pull request may close these issues.

2 participants