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

[UIActions] Embeddable and data plugin triggers/actions race condition #90929

Closed
Dosant opened this issue Feb 10, 2021 · 3 comments · Fixed by #90944
Closed

[UIActions] Embeddable and data plugin triggers/actions race condition #90929

Dosant opened this issue Feb 10, 2021 · 3 comments · Fixed by #90944
Assignees
Labels
blocker bug Fixes for quality problems that affect the customer experience Feature:UIActions UI actions. These are client side only, not related to the server side actions.. v7.12.0

Comments

@Dosant
Copy link
Contributor

Dosant commented Feb 10, 2021

Kibana version: master, 7.x

Steps to reproduce:

This is hard to catch race conditions. Appeared in builds.

saved objects tagging - functional tests table listing before all hook in table listing

This would happen when data plugin setup is called before embeddable plugin setup:

  1. Embeddable registers a trigger:
    uiActions.registerTrigger(valueClickTrigger);
  2. Data plugin attaches an action to a trigger:
    uiActions.addTriggerAction(
    'VALUE_CLICK_TRIGGER',
    createValueClickAction(() => ({
    uiActions: startServices().plugins.uiActions,
    }))
    );

Data plugin and embeddable plugin do not have an explicit dependency on each other. So it could happen that the data plugin is loaded before the embeddable plugin and it is causing an error.

This is most likely a regression since #82791

possible solutions:

  1. Try to move registering actions to a start phase in data plugin
  2. Make data depend on embeddable?
  3. move those triggers to data plugin?
@Dosant Dosant added bug Fixes for quality problems that affect the customer experience Team:AppServices Feature:UIActions UI actions. These are client side only, not related to the server side actions.. labels Feb 10, 2021
@elasticmachine
Copy link
Contributor

Pinging @elastic/kibana-app-services (Team:AppServices)

@Dosant
Copy link
Contributor Author

Dosant commented Feb 10, 2021

Added a blocker level because I assume this theoretically could appear pretty often depending on network conditions.

@lukeelmers
Copy link
Member

TLDR I think modifying the trigger context typings and going with option (3) (move to data plugin) is probably the right move here, but here are a few more thoughts:

  1. Try to move registering actions to a start phase in data plugin

That would probably work, but doesn't resolve the issue of the implicit dependency we have here.

  1. Make data depend on embeddable?

IIRC from #82791, I tried this and it created another circular dependency between data > embeddable > saved_objects_management > data

  1. move those triggers to data plugin?

This could be an option, but TBH the source of a lot of issues I ran into relates to the way the actions/trigger contexts are typed. Many of these triggers have embeddable in their context and are mixing with other domains. For example value click has an embeddable, but also some data fields which would otherwise make sense to live in the data plugin:

export interface ValueClickContext<T extends IEmbeddable = IEmbeddable> {
embeddable?: T;
data: {
data: Array<{
table: Pick<Datatable, 'rows' | 'columns'>;
column: number;
row: number;
value: any;
}>;
timeFieldName?: string;
negate?: boolean;
};
}

This makes it really hard to relocate them because you either need to declare a dependency on embeddable wherever they live, or you need to fake it like I did here:

export interface ValueClickContext {
// Need to make this unknown to prevent circular dependencies.
// Apps using this property will need to cast to `IEmbeddable`.
embeddable?: unknown;
data: {
data: Array<{
table: Pick<Datatable, 'rows' | 'columns'>;
column: number;
row: number;
value: any;
}>;
timeFieldName?: string;
negate?: boolean;
};
}

This requires downstream folks relying on this piece of context to cast to IEmbeddable, which is less convenient but also more explicit as they will have to then depend on embeddable to have things typed correctly. For that reason (explicitness), I prefer this approach... but take all of this with a grain of salt as I don't know the ui actions service very well 😉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocker bug Fixes for quality problems that affect the customer experience Feature:UIActions UI actions. These are client side only, not related to the server side actions.. v7.12.0
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants