-
Notifications
You must be signed in to change notification settings - Fork 31
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
Add hybrid plugin system #1360
Add hybrid plugin system #1360
Conversation
d0fe8b1
to
be1c50b
Compare
Set to Draft state pending #1348 |
44c918e
to
fc1d533
Compare
For reference, output of "ABI diff check" CI job, before I update the ABI snapshot... TLDR: it's just saying there's a new class, so there's no need to flag a breaking change in the release notes.
|
f9950cf
to
2fd7ad0
Compare
57f7fdf
to
9558e3f
Compare
c69d98a
to
95fa9f5
Compare
Taken from the PR description above. But 'In most cases', what do you mean? Is there another mechanism? EDIT: reading further, is it
that as a merging process different from choosing from the order in the ctor, that you meant? |
...tio-core/include/openassetio/pluginSystem/HybridPluginSystemManagerImplementationFactory.hpp
Show resolved
Hide resolved
src/openassetio-core/src/pluginSystem/HybridPluginSystemManagerImplementationFactory.cpp
Outdated
Show resolved
Hide resolved
src/openassetio-core/src/pluginSystem/HybridPluginSystemManagerImplementationFactory.cpp
Outdated
Show resolved
Hide resolved
src/openassetio-core/src/pluginSystem/HybridPluginSystemManagerImplementationFactory.cpp
Outdated
Show resolved
Hide resolved
...tio-python/tests/package/pluginSystem/test_hybridpluginsystemmanagerimplementationfactory.py
Outdated
Show resolved
Hide resolved
...tio-python/tests/package/pluginSystem/test_hybridpluginsystemmanagerimplementationfactory.py
Show resolved
Hide resolved
...tio-python/tests/package/pluginSystem/test_hybridpluginsystemmanagerimplementationfactory.py
Outdated
Show resolved
Hide resolved
...tio-python/tests/package/pluginSystem/test_hybridpluginsystemmanagerimplementationfactory.py
Outdated
Show resolved
Hide resolved
...tio-python/tests/package/pluginSystem/test_hybridpluginsystemmanagerimplementationfactory.py
Show resolved
Hide resolved
Yes exactly. Most of the methods have a similar pattern - choose the "first" plugin that satisfies the capability, where "first" corresponds to the order the child factories were passed in the ctor. But for some methods that doesn't make sense or isn't possible, such as |
95fa9f5
to
567326a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The pybind11 question is open for me, but otherwise, I don't see anything outstanding.
a8fde7b
to
e1b3f94
Compare
Thanks! Squashed it all down and pushed. Let's see if there's any takers for pybind stuff. At least its only a tiny part of the PR. |
e1b3f94
to
e62da7a
Compare
e62da7a
to
c50d789
Compare
Closes OpenAssetIO#1202. OpenAssetIO currently supports two different manager plugin backends in the core library, Python and C++. We expect more backends to be added in the future. For example, there has been active investigation into a gRPC backend. By "backend" we specifically mean an implementation of the abstract base class `ManagerImplementationFactoryInterface`. The host application chooses an implementation, then injects it into a `ManagerFactory`, which is then responsible for producing `Manager` instances that the host application can use. The idea of a hybrid plugin system is to allow multiple backend plugin providers to be composed, such that API calls can be routed to the most appropriate plugin. For example, performance-critical API requests could route to a C++ plugin, whilst less critical requests route to a Python plugin. As an added bonus, having a built-in facility to compose multiple backends reduces boilerplate for hosts that wish to support multiple plugin system backends. So add a `HybridPluginSystemManagerImplementationFactory`, which implements the `ManagerImplementationFactoryInterface` interface, and takes a list of child `ManagerImplementationFactoryInterface` implementations during construction. The host application can then provide an instance of a hybrid factory to their `ManagerFactory`, taking care of the boilerplate of managing multiple plugin systems. When a host application attempts to load a plugin with a particular unique identifier, then all child plugin systems are searched. If a match is found in a single plugin system, then its manager implementation is returned directly. If a match is found in multiple plugin systems, then a proxy manager is constructed that routes calls to the appropriate manager implementation. The "appropriate" manager implementation to route to varies. In most cases, the highest priority implementation that advertises the capability associated with the API call is chosen (i.e. it is routed based on the response of the manager(s) to `hasCapability(...)`). The priority order of implementations corresponds to the order of the child factories in the list that was provided to the hybrid factory on construction. Some API methods don't have an associated capability. For these, routing is "common sense": For `initialize`, all implementations are provided with all the settings. For example, if using a `.toml` OpenAssetIO config file (see `OPENASSETIO_DEFAULT_CONFIG`), then the settings in that file will be provided to _all_ the matching manager implementations. This could cause problems if two plugins use the same settings key but require different values. Future work may look at ways to disambiguate. For `identifier` and `displayName` the highest priority manager implementation is chosen. For `info` and `settings`, the results of all manager implementations are merged, with the highest priority manager taking precedence if any dictionary keys conflict. For `flushCaches` all manager implementations are flushed. Signed-off-by: David Feltell <[email protected]>
Part of OpenAssetIO#1202. The hybrid plugin system should be the default choice for host applications, given it reduces boilerplate and allows composing plugins. So update the simppleResolver example terminal host to make use of this new best practice. Signed-off-by: David Feltell <[email protected]>
Part of OpenAssetIO#1202. Now that the hybrid plugin system is available, the `openassetio.test.manager` API Compliance test suite can use it to validate C++, Python, and composite plugins. Integration testing is provided by the SimpleCppManager unit tests, as well as the BAL integration tests in GitHub CI (`integrations.yml`). There are no explicit tests using the API Compliance suite on a hybridized plugin, yet. Signed-off-by: David Feltell <[email protected]>
c50d789
to
cbf086c
Compare
Description
Closes #1202.
OpenAssetIO currently supports two different manager plugin backends in the core library, Python and C++. We expect more backends to be added in the future. For example, there has been active investigation into a gRPC backend.
By "backend" we specifically mean an implementation of the abstract base class
ManagerImplementationFactoryInterface
. The host application chooses an implementation, then injects it into aManagerFactory
, which is then responsible for producingManager
instances that the host application can use.The idea of a hybrid plugin system is to allow multiple backend plugin providers to be composed, such that API calls can be routed to the most appropriate plugin. For example, performance-critical API requests could route to a C++ plugin, whilst less critical requests route to a Python plugin.
As an added bonus, having a built-in facility to compose multiple backends reduces boilerplate for hosts that wish to support multiple plugin system backends.
So add a
HybridPluginSystemManagerImplementationFactory
, which implements theManagerImplementationFactoryInterface
interface, and takes a list of childManagerImplementationFactoryInterface
implementations during construction. The host application can then provide an instance of a hybrid factory to theirManagerFactory
, taking care of the boilerplate of managing multiple plugin systems.When a host application attempts to load a plugin with a particular unique identifier, then all child plugin systems are searched. If a match is found in a single plugin system, then its manager implementation is returned directly. If a match is found in multiple plugin systems, then a proxy manager is constructed that routes calls to the appropriate manager implementation.
The "appropriate" manager implementation to route to varies. In most cases, the highest priority implementation that advertises the capability associated with the API call is chosen (i.e. it is routed based on the response of the manager(s) to
hasCapability(...)
).The priority order of implementations corresponds to the order of the child factories in the list that was provided to the hybrid factory on construction.
Some API methods don't have an associated capability. For these, routing is "common sense":
For
initialize
, all implementations are provided with all the settings. For example, if using a.toml
OpenAssetIO config file (seeOPENASSETIO_DEFAULT_CONFIG
), then the settings in that file will be provided to all the matching manager implementations. This could cause problems if two plugins use the same settings key but require different values. Future work may look at ways to disambiguate.For
identifier
anddisplayName
the highest priority manager implementation is chosen.For
info
andsettings
, the results of all manager implementations are merged, with the highest priority manager taking precedence if any dictionary keys conflict.For
flushCaches
all manager implementations are flushed.Reviewer Notes
See Jupyter Notebook for illustration in OpenAssetIO/OpenAssetIO-MediaCreation#99