-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Fix] check if callback is nil before calling it #1036
Conversation
I report an bug #1040 that can be fixed in this PR, if it is confirmed, I can add a commit to fix it here. @liangyepianzhou @RobertIndie @merlimat |
041fd4a
to
189ac73
Compare
@gunli Hi, Thanks for your contribution! It is enough to check if the callback is nil when the user pass. pulsar-client-go/pulsar/producer_partition.go Lines 1102 to 1105 in 3da3e5d
BTW: Please add unit test. |
No, the callback here is just the signature, users can input a nil one, and the input one can be passed everywhere. func (p *producer) SendAsync(ctx context.Context, msg *ProducerMessage,
callback func(MessageID, *ProducerMessage, error)) {
p.getPartition(msg).SendAsync(ctx, msg, callback)
}
func (p *partitionProducer) SendAsync(ctx context.Context, msg *ProducerMessage,
callback func(MessageID, *ProducerMessage, error)) {
p.internalSendAsync(ctx, msg, callback, false)
}
func (p *partitionProducer) internalSendAsync(ctx context.Context, msg *ProducerMessage,
callback func(MessageID, *ProducerMessage, error), flushImmediately bool) {
// Register transaction operation to transaction and the transaction coordinator.
var newCallback func(MessageID, *ProducerMessage, error)
var txn *transaction
if msg.Transaction != nil {
transactionImpl := (msg.Transaction).(*transaction)
txn = transactionImpl
if transactionImpl.state != TxnOpen {
p.log.WithField("state", transactionImpl.state).Error("Failed to send message" +
" by a non-open transaction.")
callback(nil, msg, newError(InvalidStatus, "Failed to send message by a non-open transaction."))
return
}
if err := transactionImpl.registerProducerTopic(p.topic); err != nil {
callback(nil, msg, err)
return
}
if err := transactionImpl.registerSendOrAckOp(); err != nil {
callback(nil, msg, err)
}
newCallback = func(id MessageID, producerMessage *ProducerMessage, err error) {
callback(id, producerMessage, err)
transactionImpl.endSendOrAckOp(err)
}
} else {
newCallback = callback
}
if p.getProducerState() != producerReady {
// Producer is closing
newCallback(nil, msg, errProducerClosed)
return
}
// bc only works when DisableBlockIfQueueFull is false
bc := make(chan struct{})
// callbackOnce make sure the callback is only invoked once in chunking
callbackOnce := &sync.Once{}
sr := &sendRequest{
ctx: ctx,
msg: msg,
callback: newCallback,
callbackOnce: callbackOnce,
flushImmediately: flushImmediately,
publishTime: time.Now(),
blockCh: bc,
closeBlockChOnce: &sync.Once{},
transaction: txn,
}
p.options.Interceptors.BeforeSend(p, msg)
p.dataChan <- sr
if !p.options.DisableBlockIfQueueFull {
// block if queue full
<-bc
}
} |
Why not verify that callback cannot be nil at the beginning of the |
Do you mean to throw an error when the callback is nil? The user is currently able to pass the nil as the callback. If we verify it and raise the error, then it will introduce the breaking change here. I think it's helpful to allow the user to pass the nil callback in some cases. |
(If this PR fixes a github issue, please add
Fixes #<xyz>
.)Fixes #
(or if this PR is one task of a github issue, please add
Master Issue: #<xyz>
to link to the master issue.)Master Issue: #
Motivation
In pulsar/producer_partition.go, there are many cases that calling the callback without checking if it is nil or not, it will be panic if the input callback is nil at runtime.
Modifications
Verifying this change
(Please pick either of the following options)
This change is a trivial rework / code cleanup without any test coverage.
(or)
This change is already covered by existing tests, such as (please describe tests).
(or)
This change added tests and can be verified as follows:
(example:)
Does this pull request potentially affect one of the following parts:
If
yes
was chosen, please highlight the changesDocumentation