Package com.linkedin.venice.listener
Class ReadQuotaEnforcementHandler
java.lang.Object
io.netty.channel.ChannelHandlerAdapter
io.netty.channel.ChannelInboundHandlerAdapter
io.netty.channel.SimpleChannelInboundHandler<RouterRequest>
com.linkedin.venice.listener.ReadQuotaEnforcementHandler
- All Implemented Interfaces:
RoutingDataRepository.RoutingDataChangedListener,StoreDataChangedListener,io.netty.channel.ChannelHandler,io.netty.channel.ChannelInboundHandler
@Sharable
public class ReadQuotaEnforcementHandler
extends io.netty.channel.SimpleChannelInboundHandler<RouterRequest>
implements RoutingDataRepository.RoutingDataChangedListener, StoreDataChangedListener
-
Nested Class Summary
Nested ClassesNested classes/interfaces inherited from interface io.netty.channel.ChannelHandler
io.netty.channel.ChannelHandler.Sharable -
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionReadQuotaEnforcementHandler(VeniceServerConfig serverConfig, ReadOnlyStoreRepository storeRepository, CompletableFuture<HelixCustomizedViewOfflinePushRepository> customizedViewRepository, String nodeId, AggServerQuotaUsageStats stats) ReadQuotaEnforcementHandler(VeniceServerConfig serverConfig, ReadOnlyStoreRepository storeRepository, CompletableFuture<HelixCustomizedViewOfflinePushRepository> customizedViewRepository, String nodeId, AggServerQuotaUsageStats stats, Clock clock) -
Method Summary
Modifier and TypeMethodDescriptionvoidchannelRead0(io.netty.channel.ChannelHandlerContext ctx, RouterRequest request) enforceQuota(RouterRequest request) Enforce quota for a given request.Helper methods for unit testingprotected static doublegetNodeResponsibilityForQuota(PartitionAssignment partitionAssignment, String nodeId) Recalculates the amount of quota that this node should serve given the partition assignment.static intgetRcu(RouterRequest request) Initially, this is the key count.getStats()voidhandleStoreChanged(Store store) This is where we add newTokenBucketfor new store version and remove irrelevant ones.voidhandleStoreCreated(Store store) Do NOT try to acquire the lock of store repository again in the implementation, otherwise a dead lock issue will happen.voidhandleStoreDeleted(String storeName) final voidinit()Initialize token buckets for all resources in the customized view repository.booleanWe only ever expect the initialized value to flip from false to true, but that initialization might happen in a different thread.voidonCustomizedViewAdded(PartitionAssignment partitionAssignment) voidonCustomizedViewChange(PartitionAssignment partitionAssignment) voidonExternalViewChange(PartitionAssignment partitionAssignment) Handle routing data changed event.voidonPartitionStatusChange(String topic, ReadOnlyPartitionStatus partitionStatus) voidonRoutingDataDeleted(String kafkaTopic) Methods inherited from class io.netty.channel.SimpleChannelInboundHandler
acceptInboundMessage, channelReadMethods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelActive, channelInactive, channelReadComplete, channelRegistered, channelUnregistered, channelWritabilityChanged, exceptionCaught, userEventTriggeredMethods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, handlerAdded, handlerRemoved, isSharableMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface io.netty.channel.ChannelHandler
handlerAdded, handlerRemovedMethods inherited from interface com.linkedin.venice.meta.StoreDataChangedListener
handleStoreDeleted
-
Field Details
-
SERVER_OVER_CAPACITY_MSG
- See Also:
-
INVALID_REQUEST_RESOURCE_MSG
- See Also:
-
-
Constructor Details
-
ReadQuotaEnforcementHandler
public ReadQuotaEnforcementHandler(VeniceServerConfig serverConfig, ReadOnlyStoreRepository storeRepository, CompletableFuture<HelixCustomizedViewOfflinePushRepository> customizedViewRepository, String nodeId, AggServerQuotaUsageStats stats) -
ReadQuotaEnforcementHandler
public ReadQuotaEnforcementHandler(VeniceServerConfig serverConfig, ReadOnlyStoreRepository storeRepository, CompletableFuture<HelixCustomizedViewOfflinePushRepository> customizedViewRepository, String nodeId, AggServerQuotaUsageStats stats, Clock clock)
-
-
Method Details
-
getRcu
Initially, this is the key count. As we develop a more accurate capacity model, this method can be refined.- Parameters:
request-- Returns:
-
getNodeResponsibilityForQuota
protected static double getNodeResponsibilityForQuota(PartitionAssignment partitionAssignment, String nodeId) Recalculates the amount of quota that this node should serve given the partition assignment. Assumes each partition gets an even portion of quota, and for each partition divides the quota by the readyToServe instances.- Parameters:
partitionAssignment-nodeId-- Returns:
-
init
public final void init()Initialize token buckets for all resources in the customized view repository. -
isInitialized
public boolean isInitialized()We only ever expect the initialized value to flip from false to true, but that initialization might happen in a different thread. By only checking the volatile variable if it is false, we guarantee that we see the change as early as possible and also allow the thread to cache the value once it goes true.- Returns:
-
enforceQuota
Enforce quota for a given request. This is common to both HTTP and GRPC handlers. Respective handlers will take actions such as retaining the request and passing it to the next handler, or sending an error response.- Parameters:
request- RouterRequest- Returns:
- QuotaEnforcementResult
-
channelRead0
- Specified by:
channelRead0in classio.netty.channel.SimpleChannelInboundHandler<RouterRequest>
-
onExternalViewChange
Description copied from interface:RoutingDataRepository.RoutingDataChangedListenerHandle routing data changed event.- Specified by:
onExternalViewChangein interfaceRoutingDataRepository.RoutingDataChangedListener- Parameters:
partitionAssignment- Newest partitions assignments information including resource name and all of instances assigned to this resource. If the number of partition is 0, it means the kafka topic is deleted.
-
onCustomizedViewChange
- Specified by:
onCustomizedViewChangein interfaceRoutingDataRepository.RoutingDataChangedListener
-
onCustomizedViewAdded
- Specified by:
onCustomizedViewAddedin interfaceRoutingDataRepository.RoutingDataChangedListener
-
onPartitionStatusChange
- Specified by:
onPartitionStatusChangein interfaceRoutingDataRepository.RoutingDataChangedListener
-
onRoutingDataDeleted
- Specified by:
onRoutingDataDeletedin interfaceRoutingDataRepository.RoutingDataChangedListener
-
handleStoreCreated
Description copied from interface:StoreDataChangedListenerDo NOT try to acquire the lock of store repository again in the implementation, otherwise a dead lock issue will happen.- Specified by:
handleStoreCreatedin interfaceStoreDataChangedListener
-
handleStoreDeleted
- Specified by:
handleStoreDeletedin interfaceStoreDataChangedListener
-
handleStoreChanged
This is where we add newTokenBucketfor new store version and remove irrelevant ones. We should keep the same number of token buckets as the number of active versions. This is because readers like FC might be lagging behind or vice versa. This way quota will still be enforced properly during the version swap or transition period.- Specified by:
handleStoreChangedin interfaceStoreDataChangedListener
-
getActiveStoreVersions
Helper methods for unit testing -
getStoreRepository
-
getStats
-