-
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
[Service Bus] Allow timeout lesser than 60 seconds #8805
[Service Bus] Allow timeout lesser than 60 seconds #8805
Conversation
…rvice-bus to the core-amqp
sdk/core/core-amqp/src/retry.ts
Outdated
@@ -26,6 +26,27 @@ function isDelivery(obj: any): boolean { | |||
return result; | |||
} | |||
|
|||
/** | |||
* TODO: We should question whether it's even a legitimate way of setting the 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.
A faithful port, even of the TODO comment questioning the legitimacy of the function. ;)
sdk/core/core-amqp/src/retry.ts
Outdated
* @param {(RetryOptions | undefined)} retryOptions | ||
* @returns {number} | ||
*/ | ||
export function getRetryAttemptTimeoutInMs(retryOptions: RetryOptions | undefined): 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.
Are we just going to remove this function anyways though when you go through and obliterate the "must be 60 seconds or less"? Ie, should we just not bother doing this so we don't have to re-release core-amqp?
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.
Do we even need to bother with this? I think you have another issue that will obviate this entire function's existence.
sdk/core/core-amqp/src/retry.ts
Outdated
typeof retryOptions.timeoutInMs !== "number" || | ||
!isFinite(retryOptions.timeoutInMs) || | ||
// TODO: not sure what the justification is for always forcing at least 60 seconds. | ||
retryOptions.timeoutInMs < Constants.defaultOperationTimeoutInMs |
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.
Now that we have decided to not put a min value of 60 seconds, the only thing we are doing is to replace invalid values with the default value. In most places before we get to using getRetryAttemptTimeoutInMs
, we would have already defaulted to {}
if there was no retry options. So, the invalid values being referred to are
- not being a number
- not being finite
- not being 0 or less
Can we not make these checks in one single place i.e when user creates ServiceBusClient and remove the need for the helper altogether?
If we are going to have a helper method for this, then shouldnt other properties in the retry options also get that treatment?
Currently we dont, because the retry() method takes care of using the right defaults and timeout is the only retry option that is used outside of the retry() method.
What am getting to is that by looking at what is exposed from core-amqp, it is not clear why timeout is the special one that needs special handling.
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 we not make these checks in one single place i.e when user creates ServiceBusClient and remove the need for the helper altogether?
Just did that for service-bus.
What am getting to is that by looking at what is exposed from core-amqp, it is not clear why timeout is the special one that needs special handling.
Un-done changes to core-amqp
* @internal | ||
* @ignore | ||
*/ | ||
export function normalizeRetryOptions( |
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 this was already done at SBC level, I see no point in keeping it now.
…to harshan/sb/issue/8192-part5
Fixes #8193 |
this._clientOptions.retryOptions | ||
); | ||
|
||
// Invalid timeouts, non-positive timeouts are defaulted to the `Constants.defaultOperationTimeoutInMs` |
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.
Why is it that we don't just throw an Error?
// Invalid timeouts, non-positive timeouts are defaulted to the `Constants.defaultOperationTimeoutInMs` | ||
const timeoutInMs = this._clientOptions.retryOptions.timeoutInMs; | ||
this._clientOptions.retryOptions.timeoutInMs = | ||
typeof timeoutInMs !== "number" || !isFinite(timeoutInMs) || timeoutInMs <= 0 |
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.
Why would zero have to be mapped? It's valid?
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 looks fine to me. I feel a little bit odd that we remap zero but I think it makes sense in that it's more like "0 is basically the uninitialized state, and should just use a default value".
It does seem like we should just throw in the face of other bogus input, however.
Based on offline discussions, the decision is to throw errors when the timeout value is 0 or -ve value |
But now, would that be a breaking change? As someone passing -ve or 0 to event hubs would now get an error from the next update :( |
Only update service-bus to throw errors for the invalid timeouts and leave event-hubs as it is, take care of event-hubs at the next major update? |
if (typeof timeoutInMs !== "number" || !isFinite(timeoutInMs) || timeoutInMs <= 0) { | ||
throw new Error(`${timeoutInMs} is an invalid value for retryOptions.timeoutInMs`); | ||
} | ||
this._clientOptions.retryOptions.timeoutInMs = timeoutInMs; |
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.
Do we have to set the timeout to the default value here? This forces us to use !
every time we want to use retryOptions.timeoutInMs
in all other places.
Since the interface allows the timeout to not be set at all, I would suggest that we only do the error check here and copy over the timeoutInMs == undefined ? Constants.defaultOperationTimeoutInMs : timeoutInMs;
to each place where the timeout is 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.
Updated messageSender with this, the other methods already have this. And thus avoided !
at all the 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.
So, now that all consumers of retry options will check for undefined and fallback to the default value, do you need the above where you set this._clientOptions.retryOptions.timeoutInMs
?
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.
Ah, if the timeout is undefined, typeof timeoutInMs !== "number"
will be satisfied and an error is thrown. I thought it to be an overkill to allow undefined by placing more guards.
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.
Then add the timeout != undefined
to your if check
if (timeout != undefined && (typeof timeoutInMs !== "number" || !isFinite(timeoutInMs) || timeoutInMs <= 0))
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.
Done!!
@@ -327,7 +327,7 @@ export class MessageSender extends LinkEntity { | |||
if (this._sender!.sendable()) { | |||
try { | |||
this._sender!.sendTimeoutInSeconds = | |||
(this._retryOptions.timeoutInMs - timeTakenByInit) / 1000; | |||
(this._retryOptions.timeoutInMs! - timeTakenByInit) / 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.
In #8685, we added a guard to ensure this does not result in -ve value in Event Hubs. Can we include that in this PR for Service Bus
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.
Added
That is fine by me, but in that case lets not make any changes to Event Hubs at all in this PR |
Co-authored-by: Ramya Rao <ramya.rao.a@outlook.com>
Removed the
getRetryAttemptTimeoutInMs
from service-bus, made necessary changes at the SBC level itself.Updated event-hubs'
getRetryAttemptTimeoutInMs
to be in sync with the new proposal.Invalid and non-positive values default to the defaultOperationTimeout