Skip to content

Plugin Infrastructure Discussion #52

Description

@dwhswenson

I'm close to finishing up #43 now, and I'd appreciate some thoughts on details of how add plugin support to OPS.

Here are the big ideas of the plugin infrastructure, no matter what:

  1. We will use essentially the same plugin infrastructure for plugins providing multiple types of functionality: CLI subcommands are plugins, but so are tools to compile OPS objects from YAML/JSON, and so are (well technically, will be) components of the Wizard. This makes developing for the CLI extremely easy and means that contributions can be made without ever touching the core code. Different plugins types are distinguished by type: CLI commands are instances of OPSCommandPlugin; plugins implementing support for compiling a new engine from YAML are instances of EngineCompilerPlugin, etc. In the future, analysis tools may be developed based on the same plugin infrastructure.

  2. There are two ways of distributing plugins -- as files, or as namespace packages. Files are better for quick setups for yourself or a small group. To distribute to a wider audience (and have a more convenient mechanism for providing updates), use a namespace package.

My main question is: Should we use one location for all plugins, or a specific location for each plugin type? Command plugins can currently be installed in the namespace paths_cli_plugins or in the user's ~/.openpathsampling/cli_plugins/ directory. The question is whether that same namespace should be used for other plugins, like for the wizard or for the

Advantages for the single namespace:

  • Easier for developers (package a new engine and support for it in the CLI and in the wizard all in Python package)
  • With New plugin infrastructure #48, it is possible to have more than one plugin in the same file, making it possible to add multiple pieces of functionality through one file-based plugin file, if all use the same namespace.
  • Easier to tell users where to put things (especially for file-based; otherwise you say "well, put this file here, that file there...")

Advantages for multiple namespaces:

  • There may be some performance advantages for multiple namespaces if users have lots of plugins. (Only search the namespace relevant to the current task.)
  • If there are enough file-based plugins, a user might find their ~/.openpathsampling/cli_plugins/ directory to be too cluttered to find the plugins they want.

Note that the default plugins for each of these are in a different default namespace, so the default plugins already have the advantages of multiple namespaces.

@sroet : Any thoughts?

Activity

  1. sroet commented on Sep 8, 2021

    @sroet
    Member

    I have a slight preference for single namespace (mainly for allowing multiple plugins per file, which makes distribution easier). Now there is one thing that should be solved: how do we deal with (accidental) namespace clashes? As that might come up (users copy a new version of the plugin without deleting the old one etc...)

  2. dwhswenson commented on Sep 8, 2021

    @dwhswenson
    MemberAuthor

    I think the solution is to error out if there is more than one plugin trying to register for the same name within the same kind of functionality. It looks like this is not done (yet) in the command plugins, but it's what I'm doing in #43. The error messages in there are already reasonably descriptive, I think:

    https://github.com/dwhswenson/openpathsampling-cli/blob/4e748999e6a4d1d9a3af5ba84de016c32fa58636/paths_cli/compiling/root_compiler.py#L72-L86

    (leading to messages like CategoryCompilerRegistrationError: The category 'engine' has already been reserved by another plugin)

    https://github.com/dwhswenson/openpathsampling-cli/blob/4e748999e6a4d1d9a3af5ba84de016c32fa58636/paths_cli/compiling/core.py#L282-L291

    (leading to messages like RuntimeError: 'openmm' is already registered with engine)

    Now, the fact that there's some repeated behavior here (plugins register under some name or names and we need to watch for duplicates) suggests that this might be something that should be refactored into a more DRY solution. But that's a very low priority right now.

    Note that technically we search the posix-style app dir (.openpathsampling) but also do the formally correct thing of searching OS-specific app dirs. This may lead to more risk of duplication, so at some point it might be worth having a little debug-plugins command to illustrate where each plugin is found.

  3. dwhswenson commented on Sep 8, 2021

    @dwhswenson
    MemberAuthor

    Also, I agree on using a single namespace. This wasn't possible before #48, so I had the idea of different namespaces for each plugin type in my head. Now that separate namespaces aren't required by technical limitations, I see no reason to add user/contributor confusion by requiring it.

    I expect that the vast majority of installed plugins will be the built-in plugins anyway (i.e., the stuff that ships in this package), which means that the main reasons for multiple namespaces are unlikely to be relevant.

  4. dwhswenson commented on Oct 26, 2021

    @dwhswenson
    MemberAuthor

    Closing this: with #43 and #54, we're definitely using the single namespace for all plugins (with plugin types differentiated by their types).

    In #43 I added paths_cli.utils.get_installed_plugins, which identifies all candidate plugins for a tuple of plugin_types:

    def get_installed_plugins(default_loader, plugin_types):
    loaders = [default_loader] + [
    FilePluginLoader(app_dir_plugins(posix=False), plugin_types),
    FilePluginLoader(app_dir_plugins(posix=True), plugin_types),
    NamespacePluginLoader('paths_cli_plugins', plugin_types)
    ]
    plugins = set(sum([loader() for loader in loaders], []))
    return list(plugins)

    We may change the directory for file-based plugins from ~/.openpathsampling/cli_plugins/ to simply ~/.openpathsampling/plugins/(or prefer plugins with cli_plugins deprecated) -- curious if there's any strong opinion on that. Namespace plugins go in paths_cli_plugins still.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions