-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
[Event Hubs] Introduce timeoutInMs #4239
Conversation
* should wait to receiver the said amount of messages. If not provided, it defaults to 60 seconds. | ||
* @param [maxWaitTimeInSeconds] | ||
* | ||
* This will no longer be used. |
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.
@ramya-rao-a Specifically anted to clarify if making this change to API is fine. This will subsequently require updates across source, tests and likely samples.
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.
Lets keep receiver changes out of scope of this PR and re-visit later
|
/** | ||
* Number of milliseconds to wait for each operation attempt to get completed within. | ||
*/ | ||
operationTimeoutInMs?: number; |
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.
Did we run the name by @bterlson?
I worry that operationTimeout
would make one think that the time applies to the entire operation and not the individual attempts
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.
Yes, the name 'operationTimeoutInMs' was decided on by Brian and it has always referred to the individual attempt/execution.
Currently though, this PR is scoped per specific changes you wanted in. The documentation/usage of RetryPolicy will need to be made clear and is likely going to have more changes based on further discussions/work we discussed offline for #2835
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.
@bterlson Given the current context of RetryPolicy related changes/usage in this PR, could you clarify if this needs to change?
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.
Since we're enforcing a minimum timeout value, I think we should document it here as well.
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.
But that's only for exponential retry correct? As I see it, that isn't supported yet
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.
To be fair, I only decided on the suffix! I agree with @ramya-rao-a that operationTimeout is misleading. perAttemptTimeoutInMs? Just timeoutInMs
may be appropriate too...
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.
@chradek was referring to #4239 (comment) when he spoke of the "minimum"
I would go with timeoutInMs
for now.
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.
Updated
eventHubPath: string, | ||
credential: TokenCredential, | ||
options?: EventHubClientOptions | ||
); |
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.
Can you check if you are using the prettier extension or not? These formatting changes shouldnt be happening
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.
Removed
options.retryOptions.operationTimeoutInMs == undefined || | ||
options.retryOptions.operationTimeoutInMs < 0 | ||
? Constants.defaultOperationTimeoutInSeconds | ||
: options.retryOptions.operationTimeoutInMs / 1000, |
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.
We had feedback that we should have a minimum value for per operation timeout, else it is easy to abuse the system by forcing frequent timeouts by giving smaller values.
Use the Constants.defaultOperationTimeoutInSeconds
as the "minimum" for now
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 see that 4ba2e14 commit has been made in an attempt to address the issue, but the change is not solving the problem at hand.
Use Constants.defaultOperationTimeoutInSeconds
as minimum value means that if user provides a value lesser than this, then we ignore user's value and use Constants.defaultOperationTimeoutInSeconds
instead
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.
Updated
* should wait to receiver the said amount of messages. If not provided, it defaults to 60 seconds. | ||
* @param [maxWaitTimeInSeconds] | ||
* | ||
* This will no longer be used. |
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.
Lets keep receiver changes out of scope of this PR and re-visit later
c5257d8
to
1d1975e
Compare
options.retryOptions.operationTimeoutInMs == undefined || | ||
options.retryOptions.operationTimeoutInMs <= 0 | ||
? Constants.defaultOperationTimeoutInSeconds * 1000 | ||
: options.retryOptions.operationTimeoutInMs |
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.
- For readability, pull this code out and have a variable/constant hold the value of the timeout
- Initializing
options
with{}
is done early on, so the checkoptions == undefined
is not needed
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.
Within the event handler it seemed to require the check, please see updated code
@@ -296,6 +296,12 @@ export class ManagementClient extends LinkEntity { | |||
maxRetries: options.retryOptions && options.retryOptions.maxRetries, | |||
abortSignal: options.abortSignal, | |||
requestName: options.requestName, | |||
timeoutInSeconds: | |||
options.retryOptions == undefined || |
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.
For readability, pull this code out and have a variable/constant hold the value of the timeout
4ba2e14
to
badb691
Compare
@ramya0820 Please avoid force pushing to an open PR, we lose track of all older comments in the Files view |
Co-Authored-By: Ramya Rao <ramya.rao.a@outlook.com>
/** | ||
* Number of milliseconds to wait for each operation attempt to get completed within. | ||
*/ | ||
operationTimeoutInMs?: number; |
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.
Since we're enforcing a minimum timeout value, I think we should document it here as well.
@@ -471,6 +471,13 @@ export class EventHubSender extends LinkEntity { | |||
options = {}; | |||
} | |||
|
|||
const operationTimeoutInMs = | |||
options.retryOptions == undefined || | |||
options.retryOptions.operationTimeoutInMs == undefined || |
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.
Maybe a safer check would be
options.retryOptions.operationTimeoutInMs == undefined || | |
typeof options.retryOptions.operationTimeoutInMs !== "number" || |
That way we don't allow it to be set to a different type in the last part of your ternary operation. Could also add an isFinite(options.retryOptions.operationTimeoutInMs
so we protect against NaN
or Infinity
(unless we want Infinity as a valid value).
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.
Nice, we should probably add these validations to other such parameters as well
@@ -323,10 +318,18 @@ export class ManagementClient extends LinkEntity { | |||
options = {}; | |||
} | |||
|
|||
const operationTimeoutInMs = | |||
options.retryOptions == undefined || |
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 logic is duplicated in eventHubReceiver
, and will probably be used by the receiver at some point. Could you refactor this into its own function that takes in either retryOptions
or operationTimeoutInMs
, and then reference this function in both places?
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.
Finding a place to house a utility like that seemed a bit tricky. Updated/created one along side RetryOptions interface definition in eventHubClient
file.
Moreover, this may change and all required validations would likely be done in one place as part of retry
module within core-amqp
eventually.
actionAfterTimeout, | ||
Constants.defaultOperationTimeoutInSeconds * 1000 | ||
); | ||
waitTimer = setTimeout(actionAfterTimeout, getRetryAttemptTimeoutInMs(options!.retryOptions)); |
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.
Just curious, was the TypeScript compiler unable to tell that options is always defined?
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.
Yeah, in the IDE I was seeing a squiggly prompt that it may be undefined..
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.
@chradek Would you prefer options && options.retryOptions
over options!.retryOptions
.
I am aware of the knee jerk reaction we get when we see the !
:)
Was just curious about what you felt about the above alternative
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 actually wonder if changing
private _trySendBatch(
message: AmqpMessage | Buffer,
tag: any,
options?: SendOptions & EventHubProducerOptions,
format?: number
): Promise<void> {
if (!options) {
options = {};
}
to
private _trySendBatch(
message: AmqpMessage | Buffer,
tag: any,
options: SendOptions & EventHubProducerOptions = {},
format?: number
): Promise<void> {
would solve the squiggles instead since then the compiler should see options
always exists.
Edit: Though if that doesn't work, I'd choose the options && options.retryOptions
route instead.
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.
Updating the type had worked
* [Event Hubs] Introduce timeoutInMs on RetryOptions (#4239) * Update event-hubs.api.md file
* [Event Hubs] Introduce timeoutInMs on RetryOptions (#4239) * Update version in constants file
Following is summary of usage of
retryOptions
and instances of applicable operation timeoutsmakeManagementRequest
relies onretryOptions
to support send requests. This already has per try operation timeout implemented incore-amqp
and just required us to make option available to users and pass it inreceive
andreceiveBatch
operations already support per try operation timeouts and allow users to configure this value usingmaxWaitTimeInSeconds
. However introducingoperationTimeoutInMs
on retryOptions to mean same thing is bound to get confusing. Should we get rid of this parameter and have users supply this using theretryOptions
? @ramya-rao-aFor more context refer to #4171