-
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] Time duration type change from ISO-8601 "string" to "number" #9430
[Service Bus] Time duration type change from ISO-8601 "string" to "number" #9430
Conversation
Co-authored-by: Richard Park <51494936+richardpark-msft@users.noreply.github.com>
/azp run js - servicebus - tests |
Azure Pipelines successfully started running 1 pipeline(s). |
@@ -228,7 +228,7 @@ export interface PeekMessagesOptions extends OperationOptions { | |||
// @public | |||
export interface QueueDescription { | |||
authorizationRules?: AuthorizationRule[]; | |||
autoDeleteOnIdle?: string; | |||
autoDeleteOnIdleInSeconds?: 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.
Wasnt the guidance to use milli seconds in general in our JS SDKs? What data type are other languages using?
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 did think of it, but usual values for this would be in "days", did not make much sense to convert days into milliseconds.
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.
.NET has a special TimeSpan type for durations.
Java is relying on a similar Duration type
Python has a similar datetime.timedelta
JS lacks such type for time duration.
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.
It seems fine to me to use seconds for 2 reasons:
- I think the ISO 8601 duration format only goes down to the second precision (though it does allow fractional seconds.)
- arm-servicebus has these properties as well (without the
InSeconds
suffix) as strings. If the fields are named differently, then I think there will be less confusion about why one package returns a string and another returns a 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.
Assuming that these properties need to work with larger timeframes like years to smaller values of seconds, are we sure that dealing with numbers is indeed more user friendly than using the ISO-8601 format?
One requires to do math, the other requires prior knowledge of ISO-8601 format.
Given that arm package will not be changing, is it worthwhile having separate treatment of these properties?
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.
One requires to do math, the other requires prior knowledge of ISO-8601 format.
I had the same dilemma while porting the tests in this PR.
are we sure that dealing with numbers is indeed more user friendly than using the ISO-8601 format?
I would prefer ISO-8601 duration format over numbers. I don't know if it is conventional or convenient for the users.
If we prefer ISO-8601 duration format, we can add the ISO_8601#Durations link in the docs for all the attributes that take ISO-8601 string inputs.
This would also be consistent with the arm package.
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, I assumed that this had already been decided in an API review. If not then I'm also fine with keeping it as a string. When we get Temporal
we can look at supporting that in the future.
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.
The call to change this was quickly made in the .Net review, but I believe that was because they have a very convenient class Duration
that is more user friendly than the ISO format.
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.
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.
After reflecting on this a bit more, it might be best to leave these as ISO strings until we get a better duration primitive to work with in JS.
…to harshan/sb/issue/9375-part2
/azp run js - servicebus - tests |
Azure Pipelines successfully started running 1 pipeline(s). |
https://dev.azure.com/azure-sdk/internal/_build/results?buildId=427839&view=results Green on Linux Node 8, Windows Node 10. |
/azp run js - servicebus - tests |
Azure Pipelines successfully started running 1 pipeline(s). |
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.
Looks good.
autoDeleteOnIdle: "P10675199DT2H48M5.4775807S", | ||
defaultMessageTtl: "P10675199DT2H48M5.4775807S", | ||
duplicateDetectionHistoryTimeWindow: "PT10M", | ||
autoDeleteOnIdleInSeconds: 10675199 * 24 * 60 * 60 + 2 * 60 * 60 + 48 * 60 + 5.4775807, //"P10675199DT2H48M5.4775807S", |
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'm having a hard time telling...do the atomManagement tests actually test that a response with the string duration is deserialized into the correct 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.
These tests have historically been testing the response with the expected hard-coded output, my intention was just to migrate to the new type.
do the atomManagement tests actually test that a response with the string duration is deserialized into the correct number?
Not exactly, I have added separate unit tests for that - "string duration is deserialized into the correct number".
For this test, we do verify the response by matching it with this predefined output.
The response would contain the iso-8601 duration converted into seconds.
If the number from the response matches with the number here in the predefined output, the test would succeed and I would assume the string duration is deserialized into the correct 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.
Some minor comments and some confusion on my end
export function getISO8601DurationFromSeconds( | ||
timeInSeconds: number | undefined | ||
): string | undefined { | ||
if (timeInSeconds == null) { |
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 make this more explicit?
if (timeInSeconds == null) { | |
if (timeInSeconds === undefined || timeInSeconds === null) { |
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 is interesting - why would we want to expand it? I was under the impression this was good practice?
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.
Many developers are not familiar with the subtleties of non-strict comparisons, so they are often banned by lint rules. It's also easy to not notice a missing extra =.
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.
And if you want to take it from Anders, we shouldn't ever use null
in our code since it's not required by the language, but I'm not that much of a purist as to avoid it for use in sentinel values. ;)
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.
Interesting.
timeInSeconds === undefined || timeInSeconds === null
To handle both null and undefined, we have been doing timeInSeconds == undefined
check at other places.
if (timeInSeconds == null) { | ||
return undefined; | ||
} | ||
if (typeof timeInSeconds != "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.
nit: !==
if (timeInSeconds == null) { | ||
return undefined; | ||
} | ||
if (typeof timeInSeconds != "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.
what about if timeInSeconds
is NaN? Or some other special value like Infinity?
let timeSeparatorAdded = false; | ||
for (const { label, inSeconds } of [day, hour, minute, second]) { | ||
const value = | ||
label == second.label |
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.
nit: another non-strict comparison
const minute = { label: "M", inSeconds: 60 }; | ||
const hour = { label: "H", inSeconds: minute.inSeconds * 60 }; | ||
const day = { label: "D", inSeconds: hour.inSeconds * 24 }; | ||
const countDecimals = |
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'm not really sure why we get how many decimal values there are, just to call toFixed of that value later. Are we trying to truncate it in a way that avoids floating point issues?
What's the case where this isn't true?
timeInSeconds.toString() === timeInSeconds.toFixed(timeInSeconds.toString().split(".")[1].length)
* Example: PT10M, P106DT2H48M5.47S | ||
* | ||
* This helper method is to convert the duration in seconds to ISO-8601 duration format. | ||
* |
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 mention here that we don't support weeks/months/years because the service doesn't send that?
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.
Good point. I've added it in the comments for one of the methods, I'll add it in the docs too.
* Example: PT10M, P106DT2H48M5.47S | ||
* | ||
* This helper method is to convert the duration in ISO-8601 format into seconds. | ||
* |
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.
again a reference to not supporting years/months/weeks would be good
Waiting for #9430 (comment) discussion to be addressed to decide the fate of the PR.. either addressing the rest of the feedback and merge or discarding the PR. |
Closing in favour of #9723 |
Issue - #9375
Attributes that follow ISO-8601 time duration format (string type)
This PR attempts to change the type to "number" with the time duration in seconds.
With that, "InSeconds" suffix would be added at the end of those four attributes.
Please provide reviews and let's finalize on the attributes.