@ -47,20 +47,20 @@ object TransactionCoordinator {
@@ -47,20 +47,20 @@ object TransactionCoordinator {
config . transactionTopicMinISR ,
config . transactionTransactionsExpiredTransactionCleanupIntervalMs )
val pi dManager = new ProducerIdManager ( config . brokerId , zkUtils )
val producerI dManager = new ProducerIdManager ( config . brokerId , zkUtils )
val txnStateManager = new TransactionStateManager ( config . brokerId , zkUtils , scheduler , replicaManager , txnConfig , time )
val txnMarkerPurgatory = DelayedOperationPurgatory [ DelayedTxnMarker ] ( "txn-marker-purgatory" , config . brokerId , reaperEnabled = false )
val txnMarkerChannelManager = TransactionMarkerChannelManager ( config , metrics , metadataCache , txnStateManager , txnMarkerPurgatory , time )
new TransactionCoordinator ( config . brokerId , scheduler , pi dManager , txnStateManager , txnMarkerChannelManager , txnMarkerPurgatory , time )
new TransactionCoordinator ( config . brokerId , scheduler , producerI dManager , txnStateManager , txnMarkerChannelManager , txnMarkerPurgatory , time )
}
private def initTransactionError ( error : Errors ) : InitPi dResult = {
InitPi dResult ( RecordBatch . NO_PRODUCER_ID , RecordBatch . NO_PRODUCER_EPOCH , error )
private def initTransactionError ( error : Errors ) : InitProducerI dResult = {
InitProducerI dResult ( RecordBatch . NO_PRODUCER_ID , RecordBatch . NO_PRODUCER_EPOCH , error )
}
private def initTransactionMetadata ( txnMetadata : TransactionMetadataTransition ) : InitPi dResult = {
InitPi dResult ( txnMetadata . producerId , txnMetadata . producerEpoch , Errors . NONE )
private def initTransactionMetadata ( txnMetadata : TransactionMetadataTransition ) : InitProducerI dResult = {
InitProducerI dResult ( txnMetadata . producerId , txnMetadata . producerEpoch , Errors . NONE )
}
}
@ -74,7 +74,7 @@ object TransactionCoordinator {
@@ -74,7 +74,7 @@ object TransactionCoordinator {
*/
class TransactionCoordinator ( brokerId : Int ,
scheduler : Scheduler ,
pi dManager : ProducerIdManager ,
producerI dManager : ProducerIdManager ,
txnManager : TransactionStateManager ,
txnMarkerChannelManager : TransactionMarkerChannelManager ,
txnMarkerPurgatory : DelayedOperationPurgatory [ DelayedTxnMarker ] ,
@ -83,22 +83,21 @@ class TransactionCoordinator(brokerId: Int,
@@ -83,22 +83,21 @@ class TransactionCoordinator(brokerId: Int,
import TransactionCoordinator._
type InitPidCallback = InitPi dResult => Unit
type InitProducerIdCallback = InitProducerI dResult => Unit
type AddPartitionsCallback = Errors => Unit
type EndTxnCallback = Errors => Unit
/* Active flag of the coordinator */
private val isActive = new AtomicBoolean ( false )
def handleInitPid ( transactionalId : String ,
transactionTimeoutMs : Int ,
responseCallback : InitPidCallback ) : Unit = {
def handleInitProducerId ( transactionalId : String ,
transactionTimeoutMs : Int ,
responseCallback : InitProducerIdCallback ) : Unit = {
if ( transactionalId == null || transactionalId . isEmpty ) {
// if the transactional id is not specified , then always blindly accept the request
// and return a new pid from the pi d manager
val pid = pidManager . nextPi d ( )
responseCallback ( InitPidResult ( pid , e poch = 0 , Errors . NONE ) )
// and return a new producerId from the producerI d manager
val producerId = producerIdManager . generateProducerI d ( )
responseCallback ( InitProducerIdResult ( producerId , producerE poch = 0 , Errors . NONE ) )
} else if ( ! txnManager . isCoordinatorFor ( transactionalId ) ) {
// check if it is the assigned coordinator for the transactional id
responseCallback ( initTransactionError ( Errors . NOT_COORDINATOR ) )
@ -108,12 +107,12 @@ class TransactionCoordinator(brokerId: Int,
@@ -108,12 +107,12 @@ class TransactionCoordinator(brokerId: Int,
// check transactionTimeoutMs is not larger than the broker configured maximum allowed value
responseCallback ( initTransactionError ( Errors . INVALID_TRANSACTION_TIMEOUT ) )
} else {
// only try to get a new pi d and update the cache if the transactional id is unknown
val result : Either [ InitPi dResult , ( Int , TransactionMetadataTransition ) ] = txnManager . getTransactionState ( transactionalId ) match {
// only try to get a new producerI d and update the cache if the transactional id is unknown
val result : Either [ InitProducerI dResult , ( Int , TransactionMetadataTransition ) ] = txnManager . getTransactionState ( transactionalId ) match {
case None =>
val pid = pidManager . nextPi d ( )
val producerId = producerIdManager . generateProducerI d ( )
val now = time . milliseconds ( )
val createdMetadata = new TransactionMetadata ( producerId = pi d ,
val createdMetadata = new TransactionMetadata ( producerId = producerI d ,
producerEpoch = 0 ,
txnTimeoutMs = transactionTimeoutMs ,
state = Empty ,
@ -129,7 +128,7 @@ class TransactionCoordinator(brokerId: Int,
@@ -129,7 +128,7 @@ class TransactionCoordinator(brokerId: Int,
// in this case we will treat it as the metadata has existed already
txnMetadata synchronized {
if ( ! txnMetadata . eq ( createdMetadata ) ) {
initPi dWithExistingMetadata ( transactionalId , transactionTimeoutMs , coordinatorEpoch , txnMetadata )
initProducerI dWithExistingMetadata ( transactionalId , transactionTimeoutMs , coordinatorEpoch , txnMetadata )
} else {
Right ( coordinatorEpoch , txnMetadata . prepareNewPid ( time . milliseconds ( ) ) )
}
@ -140,13 +139,13 @@ class TransactionCoordinator(brokerId: Int,
@@ -140,13 +139,13 @@ class TransactionCoordinator(brokerId: Int,
val txnMetadata = existingEpochAndMetadata . transactionMetadata
txnMetadata synchronized {
initPi dWithExistingMetadata ( transactionalId , transactionTimeoutMs , coordinatorEpoch , txnMetadata )
initProducerI dWithExistingMetadata ( transactionalId , transactionTimeoutMs , coordinatorEpoch , txnMetadata )
}
}
result match {
case Left ( pi dResult ) =>
responseCallback ( pi dResult )
case Left ( producerI dResult ) =>
responseCallback ( producerI dResult )
case Right ( ( coordinatorEpoch , newMetadata ) ) =>
if ( newMetadata . txnState == Ongoing ) {
@ -178,11 +177,10 @@ class TransactionCoordinator(brokerId: Int,
@@ -178,11 +177,10 @@ class TransactionCoordinator(brokerId: Int,
}
}
private def initPidWithExistingMetadata ( transactionalId : String ,
transactionTimeoutMs : Int ,
coordinatorEpoch : Int ,
txnMetadata : TransactionMetadata ) : Either [ InitPidResult , ( Int , TransactionMetadataTransition ) ] = {
private def initProducerIdWithExistingMetadata ( transactionalId : String ,
transactionTimeoutMs : Int ,
coordinatorEpoch : Int ,
txnMetadata : TransactionMetadata ) : Either [ InitProducerIdResult , ( Int , TransactionMetadataTransition ) ] = {
if ( txnMetadata . pendingTransitionInProgress ) {
// return a retriable exception to let the client backoff and retry
Left ( initTransactionError ( Errors . CONCURRENT_TRANSACTIONS ) )
@ -216,8 +214,8 @@ class TransactionCoordinator(brokerId: Int,
@@ -216,8 +214,8 @@ class TransactionCoordinator(brokerId: Int,
def handleAddPartitionsToTransaction ( transactionalId : String ,
pi d : Long ,
epoch : Short ,
producerI d : Long ,
produc erE poch: Short ,
partitions : collection.Set [ TopicPartition ] ,
responseCallback : AddPartitionsCallback ) : Unit = {
val error = validateTransactionalId ( transactionalId )
@ -225,10 +223,10 @@ class TransactionCoordinator(brokerId: Int,
@@ -225,10 +223,10 @@ class TransactionCoordinator(brokerId: Int,
responseCallback ( error )
} else {
// try to update the transaction metadata and append the updated metadata to txn log ;
// if there is no such metadata treat it as invalid pi d mapping error .
// if there is no such metadata treat it as invalid producerI d mapping error .
val result : Either [ Errors , ( Int , TransactionMetadataTransition ) ] = txnManager . getTransactionState ( transactionalId ) match {
case None =>
Left ( Errors . INVALID_PID_MAPPING )
Left ( Errors . INVALID_PRODUCER_ ID_MAPPING )
case Some ( epochAndMetadata ) =>
val coordinatorEpoch = epochAndMetadata . coordinatorEpoch
@ -236,9 +234,9 @@ class TransactionCoordinator(brokerId: Int,
@@ -236,9 +234,9 @@ class TransactionCoordinator(brokerId: Int,
// generate the new transaction metadata with added partitions
txnMetadata synchronized {
if ( txnMetadata . producerId != pi d ) {
Left ( Errors . INVALID_PID_MAPPING )
} else if ( txnMetadata . producerEpoch != epoch ) {
if ( txnMetadata . producerId != producerI d ) {
Left ( Errors . INVALID_PRODUCER_ ID_MAPPING )
} else if ( txnMetadata . producerEpoch != produc erE poch) {
Left ( Errors . INVALID_PRODUCER_EPOCH )
} else if ( txnMetadata . pendingTransitionInProgress ) {
// return a retriable exception to let the client backoff and retry
@ -274,8 +272,8 @@ class TransactionCoordinator(brokerId: Int,
@@ -274,8 +272,8 @@ class TransactionCoordinator(brokerId: Int,
}
def handleEndTransaction ( transactionalId : String ,
pi d : Long ,
epoch : Short ,
producerI d : Long ,
produc erE poch: Short ,
txnMarkerResult : TransactionResult ,
responseCallback : EndTxnCallback ) : Unit = {
val error = validateTransactionalId ( transactionalId )
@ -284,16 +282,16 @@ class TransactionCoordinator(brokerId: Int,
@@ -284,16 +282,16 @@ class TransactionCoordinator(brokerId: Int,
else {
val preAppendResult : Either [ Errors , ( Int , TransactionMetadataTransition ) ] = txnManager . getTransactionState ( transactionalId ) match {
case None =>
Left ( Errors . INVALID_PID_MAPPING )
Left ( Errors . INVALID_PRODUCER_ ID_MAPPING )
case Some ( epochAndTxnMetadata ) =>
val txnMetadata = epochAndTxnMetadata . transactionMetadata
val coordinatorEpoch = epochAndTxnMetadata . coordinatorEpoch
txnMetadata synchronized {
if ( txnMetadata . producerId != pi d )
Left ( Errors . INVALID_PID_MAPPING )
else if ( txnMetadata . producerEpoch != epoch )
if ( txnMetadata . producerId != producerI d )
Left ( Errors . INVALID_PRODUCER_ ID_MAPPING )
else if ( txnMetadata . producerEpoch != produc erE poch)
Left ( Errors . INVALID_PRODUCER_EPOCH )
else if ( txnMetadata . pendingTransitionInProgress )
Left ( Errors . CONCURRENT_TRANSACTIONS )
@ -343,9 +341,9 @@ class TransactionCoordinator(brokerId: Int,
@@ -343,9 +341,9 @@ class TransactionCoordinator(brokerId: Int,
val txnMetadata = epochAndMetadata . transactionMetadata
txnMetadata synchronized {
if ( txnMetadata . producerId != pi d )
Left ( Errors . INVALID_PID_MAPPING )
else if ( txnMetadata . producerEpoch != epoch )
if ( txnMetadata . producerId != producerI d )
Left ( Errors . INVALID_PRODUCER_ ID_MAPPING )
else if ( txnMetadata . producerEpoch != produc erE poch)
Left ( Errors . INVALID_PRODUCER_EPOCH )
else if ( txnMetadata . pendingTransitionInProgress )
Left ( Errors . CONCURRENT_TRANSACTIONS )
@ -452,11 +450,11 @@ class TransactionCoordinator(brokerId: Int,
@@ -452,11 +450,11 @@ class TransactionCoordinator(brokerId: Int,
isActive . set ( false )
scheduler . shutdown ( )
txnMarkerPurgatory . shutdown ( )
pi dManager . shutdown ( )
producerI dManager . shutdown ( )
txnManager . shutdown ( )
txnMarkerChannelManager . shutdown ( )
info ( "Shutdown complete." )
}
}
case class InitPidResult ( pi d : Long , epoch : Short , error : Errors )
case class InitProducerIdResult ( producerI d : Long , produc erE poch: Short , error : Errors )