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

Allow plugins to upgrade global custom metadata on startup #19962

Merged
merged 1 commit into from
Aug 16, 2016

Conversation

areek
Copy link
Contributor

@areek areek commented Aug 11, 2016

Currently plugins can not inspect or upgrade custom
meta data on startup. This commit allow plugins
to check and/or upgrade global custom meta data on startup.
Plugins can stop a node if any custom meta data is not supported.

* Returns a function that upgrades metadata on startup.
* Plugins should return the input metadata if no upgrade is required
* and throw {@link IllegalStateException} to stop a node from starting
* when unsupported metadata is found.
Copy link
Member

Choose a reason for hiding this comment

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

I suggest more official Javadoc:

/**
 * Provides a function to modify the metadata on startup.
 * <p>
 * Plugins should return the input metadata via {@link Function#identity()} if no upgrade is required.
 * @return Never {@code null}. The same or upgraded {@code MetaData}.
 * @throws IllegalStateException if the node needs to be stopped because {@code MetaData} is unsupported
 */

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 docs, added :)

@pickypg
Copy link
Member

pickypg commented Aug 11, 2016

The change looks good, but we should add some tests to ensure it consistently happens.


@Nullable
private volatile MetaData previousMetaData;

private volatile Set<Index> previouslyWrittenIndices = emptySet();

@Inject
public GatewayMetaState(Settings settings, NodeEnvironment nodeEnv, MetaStateService metaStateService,
public GatewayMetaState(Settings settings, NodeEnvironment nodeEnv, PluginsService pluginsService, MetaStateService metaStateService,
Copy link
Member

Choose a reason for hiding this comment

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

This is not the way to get the custom upgraders passed around (we should not be passing around PluginService). See other examples in Node: you should collect all the upgraders, and put them into a container that will then be injected (and eventually when GatewayMetaState is deguiced, we will just have it there as an arg, instead of via injection).

@jasontedor
Copy link
Member

This pull request is missing tests. Some possible test cases:

  • What if two plugins upgrade?
  • What happens if the metadata is upgraded twice?

@rjernst
Copy link
Member

rjernst commented Aug 11, 2016

Regarding two plugins upgrade, the plugins should not be modifying the same parts of metadata (this is really for custom metadata). Another suggested test is to check upgrading actually works (ie is it called at all for plugins which add an upgrader).

@jasontedor
Copy link
Member

Regarding two plugins upgrade, the plugins should not be modifying the same parts of metadata (this is really for custom metadata).

Yes, but a test should check that both pieces of custom metadata are updated when two plugins upgrade on startup.

@areek areek force-pushed the enhancement/plugins_upgrade_hook branch 2 times, most recently from 57186d5 to d99bc98 Compare August 12, 2016 18:38
@areek
Copy link
Contributor Author

areek commented Aug 12, 2016

Thanks @pickypg, @jasontedor & @rjernst for the feedback, I have restructured the code and added unit tests upgrading. Could you take another look?

Another suggested test is to check upgrading actually works (ie is it called at all for plugins which add an upgrader).

I wonder, if we need an explicit test for this in light of the current changes? We collect the functions just like we collect the namedWritables and components

* <p>
* Plugins should return the input metadata via {@link Function#identity()} if no upgrade is required.
* @return Never {@code null}. The same or upgraded {@code MetaData}.
* @throws IllegalStateException if the node needs to be stopped because {@code MetaData} is unsupported
Copy link
Member

Choose a reason for hiding this comment

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

I would say something like "the node should not start" instead of the part about stopping (since this is during startup, while stopping implies the node is already started).

@rjernst
Copy link
Member

rjernst commented Aug 12, 2016

Thanks @areek, I left some more comments. I think the tests should actually be on GatewayMetaState. And I think there may be a subtle bug regarding that: we need to be careful in there about only loading the metastate from disk once, passing it through all of the methods to manipulate/check it, and then writing it once all checks have passed. Otherwise, for example, right now index upgrading would happen, we write the new state, the plugged in metadata converters run, and if one fails, the node cannot be downgraded.

@areek areek force-pushed the enhancement/plugins_upgrade_hook branch 2 times, most recently from e9139ad to ee06b4a Compare August 16, 2016 04:27
@areek
Copy link
Contributor Author

areek commented Aug 16, 2016

@rjernst Thanks for pointing out that node cannot be downgraded, if plugins error out on upgrade. I have separated out logic to create upgraded meta data and writing them to disk. Now plugins can validate MetaData and upgrade MetaData.Customs on startup. I made the upgrade specific to MetaData.Custom as I don't think plugins should be upgrading anything except for the customs in the meta state (at least not on startup!), while plugins should be able to prevent startup upon finding a "too-old" meta data. Additionally, meta data upgrading became more unit-testable :) WDYT?

@rjernst
Copy link
Member

rjernst commented Aug 16, 2016

@areek I think you misunderstood what I meant. I was suggesting GatewayMetaState should be modified, so that it reads the metastate at the beginning, runs it through all modifications/checks, and then writes it at the end of the ctor. I don't think we need two different interfaces for upgrade/validation. We just need to be more careful in the class calling all of these.

@areek
Copy link
Contributor Author

areek commented Aug 16, 2016

I was suggesting GatewayMetaState should be modified, so that it reads the metastate at the beginning, runs it through all modifications/checks, and then writes it at the end of the ctor

@rjernst this is what it does. Now, all the upgrading logic is in GatewayMetaState.upgradeMetaData. The reason for not exposing upgrading the entire meta data by plugins is that it makes it hard to figure what part of the meta data exactly got upgraded and makes the upgrade code complex, as it deals with upgrading index meta data already. Also, I don't see why we need plugins to be able to upgrade anything other than the customs on startup.

I agree that you can still do the validation on Plugin#getCustomMetaDataUpgrader instead of having a separate Plugin#getMetaDataValidator, but IMO, it is more readable separating the validation from the upgrade and this allows plugin to validate based on the entire meta data while upgrading only customs.

@rjernst
Copy link
Member

rjernst commented Aug 16, 2016

I don't like the validation separate because it doesn't match the purpose of the upgrade step. There should be no "validation only" possible. Think of it as upgrading is happening and it either succeeds with new meta state written, or fails with the node shutting down.

@areek
Copy link
Contributor Author

areek commented Aug 16, 2016

hmm, ok, so we should do the validation in Plugin#getCustomMetaDataUpgrader then? I don't like exposing the entire meta data to plugins to upgrade.

@rjernst
Copy link
Member

rjernst commented Aug 16, 2016

Yes, all I mean is to have one method on Plugin.

@areek areek force-pushed the enhancement/plugins_upgrade_hook branch from ee06b4a to 4236c0f Compare August 16, 2016 17:37
@areek areek changed the title Allow plugins to upgrade metadata on startup Allow plugins to upgrade global custom metadata on startup Aug 16, 2016
@areek areek force-pushed the enhancement/plugins_upgrade_hook branch from 4236c0f to f5f2811 Compare August 16, 2016 17:40
@areek
Copy link
Contributor Author

areek commented Aug 16, 2016

I removed Plugin#getMetaDataValidator in the last iteration. @rjernst WDYT?

@areek areek force-pushed the enhancement/plugins_upgrade_hook branch from f5f2811 to 4c34896 Compare August 16, 2016 17:45
customs -> {
List<MetaData.Custom> customList = new ArrayList<>();
for (MetaData.Custom custom : customs) {
if (custom.type().equals(CustomMetaData1.TYPE)) {
Copy link
Member

Choose a reason for hiding this comment

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

I notice this pattern in every implementation. Perhaps this should be a Map instead of Collection (keyed by the custom type name)? Then the map can be copied, and keys replaced, removed, or added easily, without needing to have logic for the other custom metadata that the plugin does not care about.

@rjernst
Copy link
Member

rjernst commented Aug 16, 2016

Thanks @areek. It is looking better. I left a couple more suggestions.

@areek areek force-pushed the enhancement/plugins_upgrade_hook branch from 4c34896 to 97b2546 Compare August 16, 2016 19:57
@areek
Copy link
Contributor Author

areek commented Aug 16, 2016

Thanks @rjernst for the suggestions, addressed all your feedback.

@areek areek force-pushed the enhancement/plugins_upgrade_hook branch from 97b2546 to c353ba9 Compare August 16, 2016 20:02
@rjernst
Copy link
Member

rjernst commented Aug 16, 2016

LGTM

Currently plugins can not inspect or upgrade custom
meta data on startup. This commit allow plugins
to check and/or upgrade global custom meta data on startup.
Plugins can stop a node if any custom meta data is not supported.
@areek areek force-pushed the enhancement/plugins_upgrade_hook branch from c353ba9 to 75d4a9f Compare August 16, 2016 20:25
@areek areek merged commit a61257e into elastic:master Aug 16, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants