All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.mantisrx.server.core.MantisAkkaRpcSystemLoader Maven / Gradle / Ivy

/*
 * Copyright 2022 Netflix, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package io.mantisrx.server.core;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ServiceLoader;
import java.util.UUID;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.flink.configuration.Configuration;
import org.apache.flink.configuration.CoreOptions;
import org.apache.flink.core.classloading.ComponentClassLoader;
import org.apache.flink.runtime.rpc.RpcSystem;
import org.apache.flink.runtime.rpc.RpcSystemLoader;
import org.apache.flink.util.IOUtils;

/**
 * RpcSystemLoader for mantis task executor and other services that need to expose an RPC API.
 * This particular implementation uses the akka RPC implementation under the hood.
 */
@Slf4j
public class MantisAkkaRpcSystemLoader implements RpcSystemLoader {

    private static final RpcSystem INSTANCE = createRpcSystem();

    public static RpcSystem getInstance() {
        return INSTANCE;
    }

    @Override
    public RpcSystem loadRpcSystem(Configuration config) {
        return INSTANCE;
    }

    private static RpcSystem createRpcSystem() {
        try {
            final ClassLoader flinkClassLoader = RpcSystem.class.getClassLoader();

            final Path tmpDirectory = Paths.get(System.getProperty("java.io.tmpdir") + "/flink-rpc-akka-jar");
            Files.createDirectories(tmpDirectory);

            try {
                // Best-effort cleanup directory in case some other jobs has failed abruptly
                FileUtils.cleanDirectory(tmpDirectory.toFile());
            } catch (Exception e) {
                log.warn("Could not cleanup flink-rpc-akka jar directory {}.", tmpDirectory, e);
            }
            final Path tempFile =
                Files.createFile(
                    tmpDirectory.resolve("flink-rpc-akka_" + UUID.randomUUID() + ".jar"));

            final InputStream resourceStream =
                flinkClassLoader.getResourceAsStream("flink-rpc-akka.jar");
            if (resourceStream == null) {
                throw new RuntimeException(
                    "Akka RPC system could not be found. If this happened while running a test in the IDE,"
                        + "run the process-resources phase on flink-rpc/flink-rpc-akka-loader via maven.");
            }

            IOUtils.copyBytes(resourceStream, Files.newOutputStream(tempFile));

            // The following classloader loads all classes from the submodule jar, except for explicitly white-listed packages.
            //
            //  

To ensure that classes from the submodule are always loaded through the submodule classloader // (and thus from the submodule jar), even if the classes are also on the classpath (e.g., during // tests), all classes from the "org.apache.flink" package are loaded child-first. // //

Classes related to mantis-specific or logging are loaded parent-first. // //

All other classes can only be loaded if they are either available in the submodule jar or the // bootstrap/app classloader (i.e., provided by the JDK). final ComponentClassLoader componentClassLoader = new ComponentClassLoader( new URL[] {tempFile.toUri().toURL()}, flinkClassLoader, // Dependencies which are needed by logic inside flink-rpc-akka (ie AkkaRpcService/System) which // are external to flink-rpc-akka itself (like ExecuteStageRequest in mantis-control-plane). CoreOptions.parseParentFirstLoaderPatterns( "org.slf4j;org.apache.log4j;org.apache.logging;org.apache.commons.logging;ch.qos.logback;io.mantisrx.server.worker;io.mantisrx.server.core;io.mantisrx", ""), new String[] {"org.apache.flink"}); return new CleanupOnCloseRpcSystem( ServiceLoader.load(RpcSystem.class, componentClassLoader).iterator().next(), componentClassLoader, tempFile); } catch (IOException e) { throw new RuntimeException("Could not initialize RPC system.", e); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy