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

[expressions] changes fork to use namespacing #125957

Merged
merged 13 commits into from
Mar 15, 2022

Conversation

ppisljar
Copy link
Member

@ppisljar ppisljar commented Feb 17, 2022

Summary

resolves #113379, #126472

Expressions.fork was updated to do namespacing internally. APIs stay the same. As part of the process getFunctions() had to be cleaned up and should now perform better.

Checklist

Delete any items that are not applicable to this PR.

For maintainers

@ppisljar ppisljar requested review from a team as code owners February 17, 2022 15:46
@botelastic botelastic bot added the Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) label Feb 17, 2022
@ppisljar ppisljar added release_note:skip Skip the PR/issue when compiling release notes v8.2.0 and removed Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) labels Feb 17, 2022
@botelastic botelastic bot added the Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) label Feb 28, 2022
@ppisljar ppisljar force-pushed the expressions/forks branch from 403411d to 3b22d31 Compare March 10, 2022 12:14
@ppisljar
Copy link
Member Author

@elasticmachine merge upstream

@ppisljar
Copy link
Member Author

@elasticmachine merge upstream

* Returns Kibana Platform *setup* life-cycle contract. Useful to return the
* same contract on server-side and browser-side.
*/
public setup(): ExpressionsServiceSetup {
Copy link
Contributor

@dokmic dokmic Mar 14, 2022

Choose a reason for hiding this comment

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

Using a decorator pattern here is a great idea. What do you think about breaking down the methods to make the class more straightforward?

I see the following points for this:

  • If we make methods protected, we will be able to extend this class in the future if we have to diverge server or public implementation.
  • Placing logic in separate methods should simplify readability and testability since we can test every method independently.
  • In general, it's a good practice to make methods as straightforward as possible and have only one single responsibility. The setup and start are factory methods, so it's better to keep them only producing new instances.
export class ExpressionsServiceFork implements ExpressionServiceFork {
  constructor(private namespace: string, private expressions: ExpressionsService) {
    this.registerFunction = this.registerFunction.bind(this);
  }

  setup(): ExpressionsServiceSetup {
    return {
      ...this.expressionsService,
      registerFunction: this.registerFunction,
      // ...
    };
  }

  protected registerFunction(definition: /* ... */) {
    if (typeof definition === 'function') {
      definition = definition();
    }

    return this.expressionsService.registerFunction({
      ...definition,
      namespace: this.namespace,
    });
  }
}

Some notes regarding the example above:

  • We should define protected methods as methods and not as properties so they will end up in the prototype. In this case, we will be able to use super in the extended class.
  • We should bind methods in the constructor to prevent producing new boundaries on every start/setup call.

Copy link
Member Author

Choose a reason for hiding this comment

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

  • I don't think this will be extended internally and it shouldn't be extended externally.
  • we don't want to make the methods visible on the ExpressionServiceFork class, if we make them protected how can we test this from the outside then ?
  • for me personally in this specific case readability is better as it is now, makes it obvious that the fork is just a wrapper around ExpressionsService and we don't need to do the binding

Copy link
Contributor

@dokmic dokmic Mar 15, 2022

Choose a reason for hiding this comment

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

I don't think this will be extended internally and it shouldn't be extended externally.

Well, we cannot predict that. That's not about the extension necessity but more about abstraction. Those methods seem to be like internal API and not an implementation detail. Even though we export only start and setup, they define the forked service.

we don't want to make the methods visible on the ExpressionServiceFork class, if we make them protected how can we test this from the outside then ?

That's possible to call them through an extended anonymous class. But in cases like that, we can just put related tests under the describe('method') block since it is not a private method.

for me personally in this specific case readability is better as it is now, makes it obvious that the fork is just a wrapper around ExpressionsService and we don't need to do the binding

I think it's better if we can extract those into methods. It should not make it less straightforward, but it will be more consistent with the ExpressionsService. The latter makes sense because we are actually forking that service.
If we do that, it will make the decorator pattern more visible so that it still should be clear that the class is a wrapper.

@ppisljar
Copy link
Member Author

@elasticmachine merge upstream

@ppisljar ppisljar force-pushed the expressions/forks branch from 7a20f50 to aa1fa35 Compare March 15, 2022 08:39
@ppisljar
Copy link
Member Author

@elasticmachine merge upstream

Copy link
Contributor

@dokmic dokmic left a comment

Choose a reason for hiding this comment

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

Great job! LGTM 👍

@kibana-ci
Copy link
Collaborator

💚 Build Succeeded

Metrics [docs]

Module Count

Fewer modules leads to a faster build time

id before after diff
expressions 171 172 +1

Public APIs missing comments

Total count of every public API that lacks a comment. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats comments for more detailed information.

id before after diff
expressions 1647 1708 +61

Async chunks

Total size of all lazy-loaded chunks that will be downloaded as the user navigates the app

id before after diff
canvas 1.0MB 1.0MB +24.0B

Public APIs missing exports

Total count of every type that is part of your API that should be exported but is not. This will cause broken links in the API documentation system. Target amount is 0. Run node scripts/build_api_docs --plugin [yourplugin] --stats exports for more detailed information.

id before after diff
expressions 4 5 +1

Page load bundle

Size of the bundles that are downloaded on every page load. Target size is below 100kb

id before after diff
expressions 87.5KB 88.9KB +1.5KB
Unknown metric groups

API count

id before after diff
expressions 2094 2153 +59

History

To update your PR or re-run it, just comment with:
@elasticmachine merge upstream

Copy link
Contributor

@crob611 crob611 left a comment

Choose a reason for hiding this comment

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

Presentation changes LGTM 👍

@ppisljar ppisljar merged commit 8ee46c2 into elastic:main Mar 15, 2022
@kibanamachine kibanamachine added the backport missing Added to PRs automatically when the are determined to be missing a backport. label Mar 17, 2022
@kibanamachine
Copy link
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create backports run node scripts/backport --pr 125957 or prevent reminders by adding the backport:skip label.

maksimkovalev pushed a commit to maksimkovalev/kibana that referenced this pull request Mar 18, 2022
@kibanamachine
Copy link
Contributor

Friendly reminder: Looks like this PR hasn’t been backported yet.
To create backports run node scripts/backport --pr 125957 or prevent reminders by adding the backport:skip label.

@ppisljar ppisljar added the backport:skip This commit does not require backporting label Mar 21, 2022
@kibanamachine kibanamachine removed the backport missing Added to PRs automatically when the are determined to be missing a backport. label Mar 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport:skip This commit does not require backporting Feature:ExpressionLanguage Interpreter expression language (aka canvas pipeline) release_note:skip Skip the PR/issue when compiling release notes v8.2.0
Projects
None yet
Development

Successfully merging this pull request may close these issues.

remove expressions fork in favor of namespacing
5 participants