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

Application Plugin Interface #7473

Closed

Conversation

Yaliang
Copy link
Contributor

@Yaliang Yaliang commented Feb 28, 2017

Introducing an application plugin interface can provide flexible context reference for components(for example, UI) which are built on top of Presto main.

@Yaliang
Copy link
Contributor Author

Yaliang commented Feb 28, 2017

+cc @billonahill @dabaitu

for (Map.Entry<String, Application> entry : applications.entrySet()) {
Application application = entry.getValue();
try (ThreadContextClassLoader ignored = new ThreadContextClassLoader(application.getClass().getClassLoader())) {
application.run(injector);
Copy link
Contributor

Choose a reason for hiding this comment

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

Passing Injector here won't work, since plugins can't see Presto's Guice from inside their class loader, by design. We intentionally do not expose the internal details of Presto to plugins. Anything needed by a plugin service should be explicitly part of the SPI.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

How about setting couple context groups as different ApplicationContexts in SPI just like ConnectorContext and initialize them in ApplicationManager?

Copy link
Contributor

Choose a reason for hiding this comment

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

What is a "context group"? I feel like I'm missing a lot of context around the purpose of this pull request. Can you explain more about the use case?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Initially, I suppose to bind UI on the port other than the API port here: #7106. In that PR, I just add a new module inside the PrestoServer and rebind the instance in the initialized injector to another Bootstrap, which looks hacky. I feel it would be reasonable adding an application plugin which runs on top of presto-main, and potentially passing some context instances from the initialized injector in some way. I agree that it shouldn't pass the whole injector and it shouldn't expose all internal instance to plugins.

@electrum
Copy link
Contributor

electrum commented Mar 1, 2017

At Facebook, we run an extended version of Presto. Create a module that depends on presto-main and write an extension of PrestoServer with additional modules:

public class ExtendedPresto
        extends PrestoServer
{
    public static void main(String[] args)
    {
        new ExtendedPresto().run();
    }

    @Override
    protected Iterable<? extends Module> getAdditionalModules()
    {
        return ImmutableList.of(...);
    }
}

Package it up by creating a module that is basically a copy of presto-server. You'll need the provisio-maven-plugin declaration from presto-root with <extensions>true</extensions> in order to use the <packaging>provisio</packaging> to build the server tarball.

(To be clear, we don't have a fork of Presto internally. We depend on presto-main and all other released artifacts that are published to Maven Central. All our extensions use integration points like the one described above.)

@Yaliang
Copy link
Contributor Author

Yaliang commented Mar 1, 2017

The idea of the application plugin is that the additional modules can be built within an isolated Bootstrap and with an isolated config file while are still able to refer some instances in the PrestoServer. In the example of #7106, if the config file is isolated, it would be much easier to config the port for the UI server; if the Bootstrap is isolated, it would be much easier to install the HttpServerModule. Do you think we can achieve the same goal with ExtendedPresto?

@electrum
Copy link
Contributor

electrum commented Mar 1, 2017

You can do this with ExtendedPresto. For example, one thing we do is bind a Thrift server to integrate with internal monitoring tools (using https://github.com/facebook/swift), which binds its own config classes.

return ImmutableList.of(
        new ThriftCodecModule(),
        new ThriftClientModule(),
        new ThriftServerModule(),
        new Fb303StatusModule(),
        ...);

@Yaliang
Copy link
Contributor Author

Yaliang commented Mar 1, 2017

I think the scenarios here are a little bit different. In your scenario, the additional modules are brand new, the config keys are different to those from other modules. However, I wish to add the HttpServerModule whose usage is purely for hosting UI(and potentially some URL forward for the resources related to UI) as the additional module. While the main Bootstrap

      modules.add(
             new NodeModule(),
             new DiscoveryModule(),
             new HttpServerModule(),          <-----here
             new JsonModule(),
             new JaxrsModule(true),
             new MBeanModule(),
             new JmxModule(),
             new JmxHttpModule(),
             ...);

already has HttpServerModule module serving UI, API and more. Since the module is same, they would have same property keys, which makes the things slightly difficult.

@electrum
Copy link
Contributor

electrum commented Mar 1, 2017

Are you saying you want to replace the Airlift HttpServerModule with your own version? If that's the case, we could change getAdditionalModules() to be just getModules(), letting to change/replace the entire list.

Alternatively, and/or as an interim solution, you can just fork the PrestoServer class and modify it as necessary.

@Yaliang
Copy link
Contributor Author

Yaliang commented Mar 1, 2017

I could say cleaner. The goal is letting two Airlift HttpServerModules to be installed. One is serving UI(and forwarding partial API) and the other one is serving API and the rest if any.

@Yaliang Yaliang closed this Oct 17, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants