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.
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 kafka.server.share;
import kafka.server.FetchSession;
import kafka.server.QuotaFactory;
import kafka.server.ReplicaManager;
import org.apache.kafka.clients.consumer.AcknowledgeType;
import org.apache.kafka.common.TopicIdPartition;
import org.apache.kafka.common.TopicPartition;
import org.apache.kafka.common.Uuid;
import org.apache.kafka.common.message.ShareAcknowledgeResponseData;
import org.apache.kafka.common.message.ShareFetchResponseData;
import org.apache.kafka.common.message.ShareFetchResponseData.PartitionData;
import org.apache.kafka.common.metrics.Metrics;
import org.apache.kafka.common.metrics.Sensor;
import org.apache.kafka.common.metrics.stats.Avg;
import org.apache.kafka.common.metrics.stats.Max;
import org.apache.kafka.common.metrics.stats.Meter;
import org.apache.kafka.common.protocol.Errors;
import org.apache.kafka.common.record.FileRecords.TimestampAndOffset;
import org.apache.kafka.common.requests.FetchRequest;
import org.apache.kafka.common.requests.ListOffsetsRequest;
import org.apache.kafka.common.requests.ShareFetchMetadata;
import org.apache.kafka.common.requests.ShareFetchRequest;
import org.apache.kafka.common.utils.ImplicitLinkedHashCollection;
import org.apache.kafka.common.utils.Time;
import org.apache.kafka.server.group.share.Persister;
import org.apache.kafka.server.share.CachedSharePartition;
import org.apache.kafka.server.share.ShareAcknowledgementBatch;
import org.apache.kafka.server.share.ShareSession;
import org.apache.kafka.server.share.ShareSessionCache;
import org.apache.kafka.server.share.ShareSessionKey;
import org.apache.kafka.server.util.timer.SystemTimer;
import org.apache.kafka.server.util.timer.SystemTimerReaper;
import org.apache.kafka.server.util.timer.Timer;
import org.apache.kafka.storage.internals.log.FetchParams;
import org.apache.kafka.storage.internals.log.FetchPartitionData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;
import scala.Option;
import scala.Tuple2;
import scala.jdk.javaapi.CollectionConverters;
import scala.runtime.BoxedUnit;
/**
* The SharePartitionManager is responsible for managing the SharePartitions and ShareSessions.
* It is responsible for fetching messages from the log and acknowledging the messages.
*/
public class SharePartitionManager implements AutoCloseable {
private static final Logger log = LoggerFactory.getLogger(SharePartitionManager.class);
/**
* The partition cache map is used to store the SharePartition objects for each share group topic-partition.
*/
private final Map partitionCacheMap;
/**
* The replica manager is used to fetch messages from the log.
*/
private final ReplicaManager replicaManager;
/**
* The time instance is used to get the current time.
*/
private final Time time;
/**
* The share session cache stores the share sessions.
*/
private final ShareSessionCache cache;
/**
* The fetch queue stores the share fetch requests that are waiting to be processed.
*/
private final ConcurrentLinkedQueue fetchQueue;
/**
* The process fetch queue lock is used to ensure that only one thread is processing the fetch queue at a time.
*/
private final AtomicBoolean processFetchQueueLock;
/**
* The record lock duration is the time in milliseconds that a record lock is held for.
*/
private final int recordLockDurationMs;
/**
* The timer is used to schedule the records lock timeout.
*/
private final Timer timer;
/**
* The max in flight messages is the maximum number of messages that can be in flight at any one time per share-partition.
*/
private final int maxInFlightMessages;
/**
* The max delivery count is the maximum number of times a message can be delivered before it is considered to be archived.
*/
private final int maxDeliveryCount;
/**
* The persister is used to persist the share partition state.
*/
private final Persister persister;
/**
* Class with methods to record share group metrics.
*/
private final ShareGroupMetrics shareGroupMetrics;
public SharePartitionManager(
ReplicaManager replicaManager,
Time time,
ShareSessionCache cache,
int recordLockDurationMs,
int maxDeliveryCount,
int maxInFlightMessages,
Persister persister,
Metrics metrics
) {
this(
replicaManager,
time,
cache,
new ConcurrentHashMap<>(),
recordLockDurationMs,
maxDeliveryCount,
maxInFlightMessages,
persister,
metrics
);
}
private SharePartitionManager(
ReplicaManager replicaManager,
Time time,
ShareSessionCache cache,
Map partitionCacheMap,
int recordLockDurationMs,
int maxDeliveryCount,
int maxInFlightMessages,
Persister persister,
Metrics metrics
) {
this.replicaManager = replicaManager;
this.time = time;
this.cache = cache;
this.partitionCacheMap = partitionCacheMap;
this.fetchQueue = new ConcurrentLinkedQueue<>();
this.processFetchQueueLock = new AtomicBoolean(false);
this.recordLockDurationMs = recordLockDurationMs;
this.timer = new SystemTimerReaper("share-group-lock-timeout-reaper",
new SystemTimer("share-group-lock-timeout"));
this.maxDeliveryCount = maxDeliveryCount;
this.maxInFlightMessages = maxInFlightMessages;
this.persister = persister;
this.shareGroupMetrics = new ShareGroupMetrics(Objects.requireNonNull(metrics), time);
}
// Visible for testing.
SharePartitionManager(
ReplicaManager replicaManager,
Time time,
ShareSessionCache cache,
Map partitionCacheMap,
ConcurrentLinkedQueue fetchQueue,
int recordLockDurationMs,
Timer timer,
int maxDeliveryCount,
int maxInFlightMessages,
Persister persister,
Metrics metrics
) {
this.replicaManager = replicaManager;
this.time = time;
this.cache = cache;
this.partitionCacheMap = partitionCacheMap;
this.fetchQueue = fetchQueue;
this.processFetchQueueLock = new AtomicBoolean(false);
this.recordLockDurationMs = recordLockDurationMs;
this.timer = timer;
this.maxDeliveryCount = maxDeliveryCount;
this.maxInFlightMessages = maxInFlightMessages;
this.persister = persister;
this.shareGroupMetrics = new ShareGroupMetrics(Objects.requireNonNull(metrics), time);
}
/**
* The fetch messages method is used to fetch messages from the log for the specified topic-partitions.
* The method returns a future that will be completed with the fetched messages.
*
* @param groupId The group id, this is used to identify the share group.
* @param memberId The member id, generated by the group-coordinator, this is used to identify the client.
* @param fetchParams The fetch parameters from the share fetch request.
* @param topicIdPartitions The topic-partitions to fetch messages for.
* @param partitionMaxBytes The maximum number of bytes to fetch for each partition.
*
* @return A future that will be completed with the fetched messages.
*/
public CompletableFuture