Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Copyright (c) 2008-2024, Hazelcast, Inc. All Rights Reserved.
*
* 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 com.hazelcast.jet.impl.execution.init;
import com.hazelcast.cluster.Address;
import com.hazelcast.function.ComparatorEx;
import com.hazelcast.internal.nio.Connection;
import com.hazelcast.internal.partition.IPartitionService;
import com.hazelcast.internal.serialization.InternalSerializationService;
import com.hazelcast.internal.serialization.SerializationServiceAware;
import com.hazelcast.internal.util.concurrent.ConcurrentConveyor;
import com.hazelcast.internal.util.concurrent.OneToOneConcurrentArrayQueue;
import com.hazelcast.internal.util.concurrent.QueuedPipe;
import com.hazelcast.internal.util.executor.ManagedExecutorService;
import com.hazelcast.jet.JetException;
import com.hazelcast.jet.config.JetConfig;
import com.hazelcast.jet.config.JobConfig;
import com.hazelcast.jet.config.ProcessingGuarantee;
import com.hazelcast.jet.core.Edge.RoutingPolicy;
import com.hazelcast.jet.core.Processor;
import com.hazelcast.jet.core.ProcessorSupplier;
import com.hazelcast.jet.core.TopologyChangedException;
import com.hazelcast.jet.function.RunnableEx;
import com.hazelcast.jet.impl.JetServiceBackend;
import com.hazelcast.jet.impl.JobClassLoaderService;
import com.hazelcast.jet.impl.execution.ConcurrentInboundEdgeStream;
import com.hazelcast.jet.impl.execution.ConveyorCollector;
import com.hazelcast.jet.impl.execution.ConveyorCollectorWithPartition;
import com.hazelcast.jet.impl.execution.InboundEdgeStream;
import com.hazelcast.jet.impl.execution.OutboundCollector;
import com.hazelcast.jet.impl.execution.OutboundEdgeStream;
import com.hazelcast.jet.impl.execution.ProcessorTasklet;
import com.hazelcast.jet.impl.execution.ReceiverTasklet;
import com.hazelcast.jet.impl.execution.SenderTasklet;
import com.hazelcast.jet.impl.execution.SnapshotContext;
import com.hazelcast.jet.impl.execution.StoreSnapshotTasklet;
import com.hazelcast.jet.impl.execution.Tasklet;
import com.hazelcast.jet.impl.execution.init.Contexts.ProcCtx;
import com.hazelcast.jet.impl.execution.init.Contexts.ProcSupplierCtx;
import com.hazelcast.jet.impl.util.AsyncSnapshotWriterImpl;
import com.hazelcast.jet.impl.util.ImdgUtil;
import com.hazelcast.jet.impl.util.ObjectWithPartitionId;
import com.hazelcast.logging.ILogger;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.IdentifiedDataSerializable;
import com.hazelcast.spi.impl.NodeEngineImpl;
import javax.annotation.Nonnull;
import javax.security.auth.Subject;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executor;
import java.util.function.IntFunction;
import java.util.function.Supplier;
import java.util.stream.IntStream;
import java.util.stream.Stream;
import static com.hazelcast.internal.util.ConcurrencyUtil.CALLER_RUNS;
import static com.hazelcast.internal.util.concurrent.ConcurrentConveyor.concurrentConveyor;
import static com.hazelcast.jet.config.EdgeConfig.DEFAULT_QUEUE_SIZE;
import static com.hazelcast.jet.config.JobConfigArguments.KEY_REQUIRED_PARTITIONS;
import static com.hazelcast.jet.core.Edge.DISTRIBUTE_TO_ALL;
import static com.hazelcast.jet.impl.execution.OutboundCollector.compositeCollector;
import static com.hazelcast.jet.impl.execution.TaskletExecutionService.TASKLET_INIT_CLOSE_EXECUTOR_NAME;
import static com.hazelcast.jet.impl.util.ImdgUtil.getMemberConnection;
import static com.hazelcast.jet.impl.util.ImdgUtil.readArray;
import static com.hazelcast.jet.impl.util.ImdgUtil.writeArray;
import static com.hazelcast.jet.impl.util.ImdgUtil.writeSubject;
import static com.hazelcast.jet.impl.util.PrefixedLogger.prefix;
import static com.hazelcast.jet.impl.util.PrefixedLogger.prefixedLogger;
import static com.hazelcast.jet.impl.util.Util.doWithClassLoader;
import static com.hazelcast.jet.impl.util.Util.memoize;
import static com.hazelcast.spi.impl.executionservice.ExecutionService.JOB_OFFLOADABLE_EXECUTOR;
import static java.util.Arrays.asList;
import static java.util.Arrays.stream;
import static java.util.Collections.unmodifiableList;
import static java.util.stream.Collectors.toMap;
/**
* An object sent from a master to members.
*/
public class ExecutionPlan implements IdentifiedDataSerializable {
// use same size as DEFAULT_QUEUE_SIZE from Edges. In the future we might
// want to make this configurable
private static final int SNAPSHOT_QUEUE_SIZE = DEFAULT_QUEUE_SIZE;
/** Snapshot of partition table used to route items on partitioned edges */
private Map partitionAssignment;
private JobConfig jobConfig;
private VertexDef[] vertices;
private int memberIndex;
private int memberCount;
private long lastSnapshotId;
private boolean isLightJob;
private Subject subject;
// *** Transient state below, used during #initialize() ***
private final transient List tasklets = new ArrayList<>();
private final transient Map memberConnections = new HashMap<>();
/** dest vertex id --> dest ordinal --> sender addr -> receiver tasklet */
private final transient Map>> receiverMap = new HashMap<>();
/** dest vertex id --> dest ordinal --> dest addr --> sender tasklet */
private final transient Map>> senderMap = new HashMap<>();
private final transient Map[]> localConveyorMap = new HashMap<>();
private final transient Map>> edgeSenderConveyorMap = new HashMap<>();
private final transient List processors = new ArrayList<>();
private transient PartitionArrangement ptionArrgmt;
private transient NodeEngineImpl nodeEngine;
private transient JobClassLoaderService jobClassLoaderService;
private transient long executionId;
private transient DagNodeUtil dagNodeUtil;
private final transient Set localCollectorsEdges = new HashSet<>();
// list of unique remote members
private final transient Supplier> remoteMembers = memoize(() -> {
Set remoteAddresses = new HashSet<>(partitionAssignment.keySet());
remoteAddresses.remove(nodeEngine.getThisAddress());
return remoteAddresses;
});
ExecutionPlan() {
}
ExecutionPlan(Map partitionAssignment, JobConfig jobConfig, long lastSnapshotId,
int memberIndex, int memberCount, boolean isLightJob, Subject subject, int expectedVerticesCount) {
this.partitionAssignment = partitionAssignment;
this.jobConfig = jobConfig;
this.lastSnapshotId = lastSnapshotId;
this.memberIndex = memberIndex;
this.memberCount = memberCount;
this.isLightJob = isLightJob;
this.subject = subject;
this.vertices = new VertexDef[expectedVerticesCount];
}
/**
* A method called on the members as part of the InitExecutionOperation.
* Creates tasklets, inboxes/outboxes and connects these to make them ready
* for a later StartExecutionOperation.
*/
public CompletableFuture> initialize(
NodeEngineImpl nodeEngine,
long jobId,
long executionId,
@Nonnull SnapshotContext snapshotContext,
ConcurrentMap tempDirectories,
InternalSerializationService jobSerializationService
) {
this.nodeEngine = nodeEngine;
this.jobClassLoaderService =
((JetServiceBackend) nodeEngine.getService(JetServiceBackend.SERVICE_NAME)).getJobClassLoaderService();
this.executionId = executionId;
CompletableFuture> procSuppliersInitFuture = initProcSuppliers(jobId, tempDirectories, jobSerializationService);
return procSuppliersInitFuture.thenAccept(r -> {
initDag(jobSerializationService);
this.ptionArrgmt = new PartitionArrangement(
partitionAssignment,
nodeEngine.getThisAddress(),
jobConfig.getArgument(KEY_REQUIRED_PARTITIONS) != null);
Set higherPriorityVertices = VertexDef.getHigherPriorityVertices(vertices);
for (Address destAddr : remoteMembers.get()) {
Connection conn = getMemberConnection(nodeEngine, destAddr);
if (conn == null) {
throw new TopologyChangedException("no connection to job participant: " + destAddr);
}
memberConnections.put(destAddr, conn);
}
dagNodeUtil = new DagNodeUtil(asList(vertices), partitionAssignment.keySet(), nodeEngine.getThisAddress());
createLocalConveyorsAndSenderReceiverTasklets(jobId, jobSerializationService);
for (VertexDef vertex : vertices) {
if (!dagNodeUtil.vertexExists(vertex)) {
continue;
}
ClassLoader processorClassLoader = isLightJob ? null :
jobClassLoaderService.getProcessorClassLoader(jobId, vertex.name());
Collection extends Processor> processors = doWithClassLoader(
processorClassLoader,
() -> createProcessors(vertex, vertex.localParallelism())
);
String jobPrefix = prefix(jobConfig.getName(), jobId, vertex.name());
// create StoreSnapshotTasklet and the queues to it
ConcurrentConveyor