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

Let subclasses of BaseAdapterRegistry customize the data structures. #228

Merged
merged 3 commits into from
Mar 15, 2021

Conversation

jamadden
Copy link
Member

Add extensive tests for this. Fixes #224.

Also adds test for, and fixes #227

Based on #226 so that CI runs. The first two commits aren't relevant to this PR.

I'd like to add a migration method to help existing persistent utilities convert to new data structures, but before that's done I'll open this as a draft so the general approach can be looked at.

@jamadden jamadden marked this pull request as ready for review March 1, 2021 20:02
@jamadden
Copy link
Member Author

jamadden commented Mar 1, 2021

I've added the migration method. It turns out to be useful to fix persistent registries that are suffering from the refcount issue described in #227 as well.

The next step would be to update zope.component.persistentregistry.PersistentAdapterRegistry to use PersistentList and PersistentMapping, as appropriate, for these data types. It wouldn't automatically convert anything, except when values are added/removed to the leaf of the subscribers tree; then, since we're writing anyway, it ought to convert from tuples to PersistentList as needed.

@jamadden
Copy link
Member Author

jamadden commented Mar 1, 2021

A question about the three methods I added (allRegistrations, allSubscriptions, rebuild): Should those go in an interface, or be left as "implementation specific" in this class hierarchy?

Add extensive tests for this. Fixes #224.

Also adds test for, and fixes #227

Add BAR.rebuild() to fix the refcount issue, and to change datatypes.

It works by using the new methods allRegistrations() and allSubscriptions() to re-create the data in new data structures.

This makes fresh calls to subscribe() and register(). I went this way instead of trying to manually walk the data structures and create them because the logic in those methods is fully tested.
@jamadden
Copy link
Member Author

Are there any interested reviewers? I'm really hoping to be able to release this feature soon as large registries can become a considerable pain point.

@jensens
Copy link
Member

jensens commented Mar 14, 2021

I would like to review, but at the moment my time is a bit limited. If you give me 2 more days?

@jamadden
Copy link
Member Author

Of course, certainly! That wasn't meant as a threat to merge it unreviewed. Just as a request for reviews, with context.

Copy link
Member

@ale-rt ale-rt left a comment

Choose a reason for hiding this comment

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

Smart work! I just added some small comments you can safely ignore

"""
if existing_leaf_sequence is None:
return (new_item,)
return existing_leaf_sequence + (new_item,)
Copy link
Member

Choose a reason for hiding this comment

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

I do not know if performance is an issue here, but concatenating tuples generates a new object which might have some impact on performance

Copy link
Member Author

Choose a reason for hiding this comment

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

True! But:

(a) that's what the existing code did, so there shouldn't be a regression (other than the slight cost of the added method call); and

(b) even if registering new utilities/adapters is on a critical fast path of an application (seems doubtful to me, but assumptions like that can obviously be wrong!), this is probably the least part of that, when considering actually creating the component, testing whether it needs to be added to the subscribers sequence, emitting the event about the registration, etc.

src/zope/interface/adapter.py Show resolved Hide resolved
src/zope/interface/adapter.py Show resolved Hide resolved
src/zope/interface/adapter.py Outdated Show resolved Hide resolved
except StopIteration:
return iter(())

return chain((first,), it)
Copy link
Member

Choose a reason for hiding this comment

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

Clever!

@jamadden
Copy link
Member Author

Thanks for the review @ale-rt !

Copy link
Member

@jensens jensens left a comment

Choose a reason for hiding this comment

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

A great new feature. Overall first class code! See my comments for two performance details.

src/zope/interface/adapter.py Show resolved Hide resolved
src/zope/interface/adapter.py Outdated Show resolved Hide resolved
@jamadden
Copy link
Member Author

Thanks for reviewing @jensens and @ale-rt !

@jamadden jamadden merged commit dd69666 into master Mar 15, 2021
@jamadden jamadden deleted the issue224 branch March 15, 2021 13:42
@jamadden
Copy link
Member Author

I'd like to tackle #230, and if it's easy, #229 then make a release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
3 participants