-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
metrics: separate default settings from override #5030
Conversation
Background: currently, from view's and deep linker's perspective, there is no way to discern a setting that was overridden vs. default. This makes the deep linking particularly finicky since, if a different application provides a different default for smoothing, for example, it will show up in the deep link as it does not match OSS's default 0.6. Change: this change separates default away from overrides while making it largely transparent to views.
imageContrastInMilli: contrastInMilli, | ||
}, | ||
}; | ||
}), | ||
on(actions.metricsResetImageBrightness, (state) => { | ||
const settingOverrides = {...state.settingOverrides}; | ||
delete settingOverrides['imageBrightnessInMilli']; |
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.
Double checking, does this work with property renaming, or do we need the 'declare' keyword on export interface MetricsSettings
, similar to other interfaces we protect?
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.
Thanks, you are correct. I do not intend to use declare
just for sake of the delete
so I worked around it.
I meant to test this before mailing this change out but I have forgotten it.
In my test:
interface IFoo {
apple: number;
banana: number;
};
const foo: Partial<IFoo> = {
apple: 1,
banana: 2
};
function Foo(foo: Partial<IFoo>) {
delete foo['apple'];
console.log(foo);
}
Foo(foo);
// built
var a={g:1,h:2};delete a.apple;console.log(a);
JSCompiler is unable to understand delete and the property name here.
); | ||
|
||
/** | ||
* Settings. | ||
*/ | ||
export const getMetricsSettingOverrides = createSelector( | ||
selectMetricsState, | ||
(state): MetricsState['settingOverrides'] => { |
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 think Partial<MetricsSettings>
as the return type would be more readable, to not require a jump to definition here.
return [{key: SMOOTHING_KEY, value: String(smoothing)}]; | ||
store.select(selectors.getMetricsSettingOverrides).pipe( | ||
map((settingOverrides) => { | ||
if (Number.isFinite(settingOverrides.scalarSmoothing)) { |
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.
scalarSmoothing
is never infinite, is it? Is a typeof settingOverrides.scalarSmoothing === 'undefined'
sufficient?
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.
While you are correct that I am abusing the Number.isFinite(undefined)
, I am also using it for Number.isFinite(NaN) === false)
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. Then separately, I think it would be better if metrics_reducer would be responsible for discarding NaNs, so that store-readers would not have to do this isFinite check. Right now, the settings pane does not do this check when using the selector.
PR tensorflow#5030 divided up the default setting from overrides and, in selector, we have mixed two values in selectors to make a concrete settings value. When reset, overriden values were set to `undefined` and caused the settings to be very wrong. ```ts // This resolves to {a: undefined} {...{a: 1}, ...{a: undefined}} ``` Object spread (or `assign`) does not skip a property whose value is `undefined` and causes settingOverride with undefined value to take precedence over the default value which, in the end, resolves the image brightness/contrast values to `undefined` unlike what the types indicated. In the end, this is a fault of the type system since the interface is defined as `Partial<>` and a value should really not have `undefined` value. To illustrate, ```ts interface Foo { bar: number; } // Legal; `bar` property may not exist const foo2: Partial<Foo> = { }; // Legal; `bar` is defined as `number` but here, it is `undefined` // yet it is legal. const foo3: Partial<Foo> = { bar: undefined }; ``` TypeScript 4.4 has a way to property guard against `undefined` value in a `Partial<>` type, `"exactOptionalPropertyTypes"` but TensorBoard app currently violates the type definition so we will enable the tsconfig in a subsequent changes.
PR #5030 divided up the default setting from overrides and, in selector, we have mixed two values in selectors to make a concrete settings value. When reset, overriden values were set to `undefined` and caused the settings to be very wrong. ```ts // This resolves to {a: undefined} {...{a: 1}, ...{a: undefined}} ``` Object spread (or `assign`) does not skip a property whose value is `undefined` and causes settingOverride with undefined value to take precedence over the default value which, in the end, resolves the image brightness/contrast values to `undefined` unlike what the types indicated. In the end, this is a fault of the type system since the interface is defined as `Partial<>` and a value should really not have `undefined` value. To illustrate, ```ts interface Foo { bar: number; } // Legal; `bar` property may not exist const foo2: Partial<Foo> = { }; // Legal; `bar` is defined as `number` but here, it is `undefined` // yet it is legal. const foo3: Partial<Foo> = { bar: undefined }; ``` TypeScript 4.4 has a way to property guard against `undefined` value in a `Partial<>` type, `"exactOptionalPropertyTypes"` but TensorBoard app currently violates the type definition so we will enable the tsconfig in a subsequent changes.
PR tensorflow#5030 divided up the default setting from overrides and, in selector, we have mixed two values in selectors to make a concrete settings value. When reset, overriden values were set to `undefined` and caused the settings to be very wrong. ```ts // This resolves to {a: undefined} {...{a: 1}, ...{a: undefined}} ``` Object spread (or `assign`) does not skip a property whose value is `undefined` and causes settingOverride with undefined value to take precedence over the default value which, in the end, resolves the image brightness/contrast values to `undefined` unlike what the types indicated. In the end, this is a fault of the type system since the interface is defined as `Partial<>` and a value should really not have `undefined` value. To illustrate, ```ts interface Foo { bar: number; } // Legal; `bar` property may not exist const foo2: Partial<Foo> = { }; // Legal; `bar` is defined as `number` but here, it is `undefined` // yet it is legal. const foo3: Partial<Foo> = { bar: undefined }; ``` TypeScript 4.4 has a way to property guard against `undefined` value in a `Partial<>` type, `"exactOptionalPropertyTypes"` but TensorBoard app currently violates the type definition so we will enable the tsconfig in a subsequent changes.
PR tensorflow#5030 divided up the default setting from overrides and, in selector, we have mixed two values in selectors to make a concrete settings value. When reset, overriden values were set to `undefined` and caused the settings to be very wrong. ```ts // This resolves to {a: undefined} {...{a: 1}, ...{a: undefined}} ``` Object spread (or `assign`) does not skip a property whose value is `undefined` and causes settingOverride with undefined value to take precedence over the default value which, in the end, resolves the image brightness/contrast values to `undefined` unlike what the types indicated. In the end, this is a fault of the type system since the interface is defined as `Partial<>` and a value should really not have `undefined` value. To illustrate, ```ts interface Foo { bar: number; } // Legal; `bar` property may not exist const foo2: Partial<Foo> = { }; // Legal; `bar` is defined as `number` but here, it is `undefined` // yet it is legal. const foo3: Partial<Foo> = { bar: undefined }; ``` TypeScript 4.4 has a way to property guard against `undefined` value in a `Partial<>` type, `"exactOptionalPropertyTypes"` but TensorBoard app currently violates the type definition so we will enable the tsconfig in a subsequent changes.
Background: currently, from view's and deep linker's perspective, there
is no way to discern a setting that was overridden vs. default. This
makes the deep linking particularly finicky since, if a different
application provides a different default for smoothing, for example, it
will show up in the deep link as it does not match OSS's default 0.6.
Change: this change separates default away from overrides while making
it largely transparent to views.