On 14 August 2013 14:00, PJ Eby <p...@telecommunity.com> wrote:
> On Wed, Aug 14, 2013 at 11:36 AM, Nick Coghlan <ncogh...@gmail.com> wrote:
>> * group - name of the export group to hook
>> * preupdate - export to call prior to installing/updating/removing a
>> distribution that exports this export group
>> * postupdate - export to call after installing/updating/removing a
>> distribution that exports this export group
>> * refresh - export to call to resynchronise any caches with the system
>> state. This will be invoked for every distribution on the system that
>> exports this export group any time the distribution defining the
>> export hook is itself installed or upgraded
>
> I've reread your post a few times and I'm not sure I understand it.
> Let me try and spell out a scenario to see if I've got it:
>
> * Distribution A defines a refresh hook for group 'foo.bar' -- but
> doesn't export anything in that group
> * Distribution B defines an *export* (fka "entry point") -- any export
> -- in export group 'foo.bar' -- but doesn't define any hooks
> * Distribution A's refresh hook will be notified when B is installed,
> updated, or removed

No, A's preupdate and postupdate hooks would fire when B (or any other
distro exporting the "foo.bar" group) is installed/updated/removed.
refresh() would fire only when A was installed or updated.

I realised that my proposed signature for the refresh() hook is wrong,
though, since it doesn't deal with catching up on *removed*
distributions properly. Rather than being called multiple times,
refresh() instead needs to be called with an iterable providing the
metadata for all currently installed distributions that export that
group.

> Is that what this is for?
>
> If so, my confusion is probably because of overloading of the term
> "export" in this context; among other things, it's unclear whether
> this is a separate data structure from exports themselves...  and if
> so, why?

Where "exports" is about publishing entries into an export group, the
new "export_hooks" field would be about *subscribing* to an export
group and being told about changes to it.

While you could use a naming convention to defined these hooks
directly in "exports" without colliding with the export of the group
itself, but I think it's better to separate them out so you can do
stricter validation on the permitted keys and values (the rationale is
similar to that for separating out commands from more general exports,
and exports from arbitrary metadata extensions).

You're right the name should be a key in a mapping (like "exports")
rather than a subfield in a list, though. That means I'm envisioning
something like the following:

Distribution "foo":

    "export_hooks" : {
        "foo.bar": {
            "preupdate": "foo.bar:exporter_update_started"
            "postupdate": "foo.bar:exporter_update_completed"
            "refresh": "foo.bar:resync_cache"
        }
    }

When "foo" is installed or updated, then the installer would invoke
"foo.bar.resync_cache" with an iterable of all currently installed
distributions that export the "foo.bar" export group.

Distribution "notfoo":

    "exports" : {
        "foo.bar": {}
    }

When "notfoo" is installed, updated or removed, then
"foo.bar:exporter_update_started" would be called prior to changing
anything, and "foo.bar:exporter_update_completed" would be called when
the changes had been made.

> If I were doing something like this in the existing entry point
> system, I'd do something like:
>
>   [mebs.refresh]
>   foo.bar = my.hook.module:refresh
>
> i.e., just list the hooks in an export group, using the export name to
> designate what export group is being monitored.  This approach
> leverages the fact that exports already need to be indexed, so why
> create a whole new sort of metadata just for the hooks?

Mostly so you can validate them and display them differently, and
avoid reserving any part of the shared namespace. I find documentation
is also easier when the core use cases aren't wedged into the
extension mechanisms (even if they share implementation details under
the hood).

> (But of course if I have misunderstood what you're trying to do in the
> first place, this and my other thoughts may be moot.)

I think you mostly understood it, I'm just not explaining it very well yet.

> (Oh, and btw, if a distribution has hooks for itself, then how are you
> going to invoke two different versions of the code?  Rollback
> sys.modules and reload?  Spawn another process?)

Requiring that all hook invocations happen in a subprocess sounds like
the best plan to me. The arguments all serialise nicely to JSON so
that shouldn't be too hard to arrange.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
_______________________________________________
Distutils-SIG maillist  -  Distutils-SIG@python.org
http://mail.python.org/mailman/listinfo/distutils-sig

Reply via email to