-
Notifications
You must be signed in to change notification settings - Fork 357
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
Add ability to set a client-side timeout on requests #57
Conversation
case res := <-resChan: | ||
return res, nil | ||
case <-time.After(timeout): | ||
return nil, NewError(ErrorNetwork, errors.New("ldap: timeout")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does the connection become unusable in this case? What happens if the server responds after this timeout? What if another operation is in progress at that point?
a few general comments
|
Thank you for the feedback. This behavior will apply to any LDAP requests that blocks waiting for a response. Each message has its own out channel that is stored in a channel map Below is an incomplete outline of the changes I am making: Create a public method Modify processMessages to create a timeout for all requests. case MessageRequest:
// Add to message list and write to network
l.Debug.Printf("Sending message %d", messagePacket.MessageID)
l.chanResults[messagePacket.MessageID] = messagePacket.Channel
go func(messageID int64) {
_, ok := <- time.After(l.timeout)
if ok {
message := &messagePacket{
Op: MessageTimeout,
MessageID: messageID,
}
l.sendProcessMessage()
}
}(messagePacket.messageID)
// go routine
buf := messagePacket.Packet.Bytes()
_, err := l.conn.Write(buf)
if err != nil {
l.Debug.Printf("Error Sending Message: %s", err.Error())
break
} Modify MessageFinish to close the timeout channel to stop the timeout from writing to the message channel. Remove the BindWithTimeout and SimpleBindWithTimeout methods. |
if packet == nil { | ||
return nil, NewError(ErrorNetwork, errors.New("ldap: could not retrieve response")) | ||
packetResponse, ok := <-channel | ||
packet, err = packetResponse.ReadPacket() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this will panic if packetResponse is nil
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I take it back, hadn't gotten to the nil receiver impl below... that's nonstandard enough that I think you should always check ok
before doing anything with packetResponse
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alternately, don't check ok
at all and trust the nil
receiver impl of PacketResponse
looking really good. can you update the interface in client.go, and is there a way to add a test for this? |
I'm controlling my own ldap process in our go tests, but I could test it by creating an |
if err.Error() != "ldap: connection timed out" { | ||
t.Fatalf("unexpected error: %v", err) | ||
} | ||
conn.Close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
already deferred this above
Test looks good, thanks. You can go ahead and squash to a single commit. |
6d4e0a8
to
01788e2
Compare
Add SetTimeout to Client API to configure timeout Add MessageTimeout event handler Return explicit errors from message handler
if err != nil { | ||
return nil, err | ||
} | ||
if !ok { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
check this ok
before doing anything with packetResponse
since PacketResponse#ReadPacket() that returns an error if the receiver is nil, I'm not sure we need to check for a closed channel in all those places. I think I'd rather just do this:
|
@liggitt I went ahead and made the change that you asked for. Let me know if there is anything else that you notice before it can be merged in. |
thanks, this looks good |
@liggitt can this be tagged for gopkg.in ? Being able to set client side timeout would be very useful. |
Yeah, I was just trying to decide if it was a point release or major version (since changing an interface or adding a public method can break some consumers) |
And if it was a major version, if there were any other changes we wanted to include while were at it |
tagged in v2.3.0 |
* add ModifyDN() - moddn/modrdn * Update README * add ModifyDN() to client * update docs, changes needed for go-ldap#57 * update to use msgCtx * fix missing comma, add moddn_test.go with examples * rename example functions to match the conventions for godoc * add missing parens
Update README update docs, changes needed for #57 add ModifyDN() to client update to use msgCtx fix missing comma, add moddn_test.go with examples rename example functions to match the conventions for godoc add missing parens
If the Ldap process is stopped or otherwise unresponsive,
Bind and SimpleBind will block waiting for a response.
This commit adds BindWithTimeout and SimpleBindWithTimeout to
give the developer control over the wait time. The Bind and
SimpleBind will return an error after DefaultTimeout.