Skip to content
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

[STCOR-888] RTR dynamic configuration, debugging event #1535

Open
wants to merge 16 commits into
base: master
Choose a base branch
from

Conversation

ncovercash
Copy link
Member

@ncovercash ncovercash commented Sep 18, 2024

Jira STCOR-888

This PR adds:

  • A new event RTR_FORCE_REFRESH_EVENT that forces a RTR refresh
    • This is not dispatched by stripes-core, but will aid development/debugging
  • Dynamic configuration for RTR_AT_TTL_FRACTION to allow customization from stripes.config.js and/or at runtime via ui-developer

Copy link

github-actions bot commented Sep 18, 2024

Jest Unit Test Results

  1 files  ±0   56 suites  ±0   1m 0s ⏱️ -1s
339 tests ±0  339 ✅ ±0  0 💤 ±0  0 ❌ ±0 
345 runs  +2  345 ✅ +2  0 💤 ±0  0 ❌ ±0 

Results for commit 9b13e4a. ± Comparison against base commit 0e4d2b4.

This pull request removes 2 and adds 2 tests. Note that renamed tests count towards both.
configureRtr leaves existing settings in place ‑ configureRtr leaves existing settings in place
configureRtr sets idleSessionTTL and idleModalTTL ‑ configureRtr sets idleSessionTTL and idleModalTTL
FFetch class force refresh event Invokes a refresh on RTR_FORCE_REFRESH_EVENT... ‑ FFetch class force refresh event Invokes a refresh on RTR_FORCE_REFRESH_EVENT...
configureRtr sets default values as applicable ‑ configureRtr sets default values as applicable

♻️ This comment has been updated with latest results.

Copy link

github-actions bot commented Sep 18, 2024

Bigtest Unit Test Results

192 tests  ±0   187 ✅ ±0   6s ⏱️ ±0s
  1 suites ±0     5 💤 ±0 
  1 files   ±0     0 ❌ ±0 

Results for commit 9b13e4a. ± Comparison against base commit 0e4d2b4.

This pull request removes 5 and adds 3 tests. Note that renamed tests count towards both.
      equal to check email label in english translation
      equal to check email precautions label in english translation
      equal to sent email precautions label in english translation
Chrome_129_0_0_0_(Linux_x86_64).Forgot username/password status test check email status page tests ‑ Forgot username/password status test check email status page tests should have the header with an appropriate text content
Chrome_129_0_0_0_(Linux_x86_64).Forgot username/password status test check email status page tests ‑ Forgot username/password status test check email status page tests should have the paragraph with an appropriate text content
Chrome_129_0_0_0_(Linux_x86_64).Forgot username/password status test check email status page tests ‑ Forgot username/password status test check email status page tests should have the header with an appropriate text content
      equal to check email label in english translation
Chrome_129_0_0_0_(Linux_x86_64).Forgot username/password status test check email status page tests ‑ Forgot username/password status test check email status page tests should have the paragraph with an appropriate text content
      equal to check email precautions label in english translation
Chrome_129_0_0_0_(Linux_x86_64).Forgot username/password status test check email status page tests ‑ Forgot username/password status test check email status page tests should have the paragraph with an appropriate text content
      equal to sent email precautions label in english translation

♻️ This comment has been updated with latest results.

Comment on lines 250 to 254
// We only want to configure the event listeners once, not every time
// there is a change to stripes or history. Hence, an empty dependency
// array.
// should `stripes.rtr` go here?
}, []); // eslint-disable-line react-hooks/exhaustive-deps
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@zburke can you comment on this? As-is, this configuration cannot be modified at runtime by ui-developer.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably I started with a non-empty array and it didn't work as expected, so I added the empty array as a crutch and never looked back. Your observation/criticism is fair, but I don't have time to debug this further since the only thing "broken" about it is that it can't be modified at runtime via dev-tools.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested it, and it works beautifully. Only the RTR config in ui-developer causes the effect to re-run, nothing else (not even the other config forms in developer)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does rely on not calling configureRtr on render in Root, though.

@@ -77,10 +77,27 @@ const OKAPI_FETCH_OPTIONS = {
};

export class FFetch {
constructor({ logger, store, rtrConfig }) {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

RTR config is exposed as part of the main stripes-config. Why should FFetch get passed it in a non-standard way?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Strikes me as 'better testability' if you're able to just pass the config in vs having to mock it out/provide different mocks through some other way.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair critique. @JohnC-80, do you remember if there is a particular reason we did it this way? My bet is that we were thinking "We need to pass it through the constructor because this is a regular class, not a React component, so it won't have access to the stripes object" which is true, but Noah is correct that since we can just grab the import ... we might as well just grab the import.

Copy link
Member

@zburke zburke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the delay; I got started on this and then lost track of it.

At a high-level the code changes look good. I would prefer to consolidate the event handlers into SessionEventContainer, but that's just ergonomics. If you merge without doing this, please explain why you opted not to.

src/components/Root/FFetch.test.js Outdated Show resolved Hide resolved
@@ -77,10 +77,27 @@ const OKAPI_FETCH_OPTIONS = {
};

export class FFetch {
constructor({ logger, store, rtrConfig }) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair critique. @JohnC-80, do you remember if there is a particular reason we did it this way? My bet is that we were thinking "We need to pass it through the constructor because this is a regular class, not a React component, so it won't have access to the stripes object" which is true, but Noah is correct that since we can just grab the import ... we might as well just grab the import.

Comment on lines 85 to 101
/**
* registers a listener for the RTR_FORCE_REFRESH_EVENT
*/
registerEventListener = () => {
this.globalEventCallback = () => {
this.logger.log('rtr', 'forcing rotation due to RTR_FORCE_REFRESH_EVENT');
rtr(this.nativeFetch, this.logger, this.rotateCallback, this.store.getState().okapi);
};
window.addEventListener(RTR_FORCE_REFRESH_EVENT, this.globalEventCallback);
}

/**
* unregister the listener for the RTR_FORCE_REFRESH_EVENT
*/
unregisterEventListener = () => {
window.removeEventListener(RTR_FORCE_REFRESH_EVENT, this.globalEventCallback);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All our other event handlers are consolidated within SessionEventContainer. Can we move this there too? If not why not?

Functionally it should not matter either way, but it would be nice to keep similar things in the same place.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, I don't think this can be consolidated; this handler specifically needs access to those callbacks and fields within FFetch, which SessionEventContainer has no way to access

Comment on lines 70 to 72
const rtrConfig = configureRtr(this.props.config.rtr);
// FFetch relies on some of these properties, so we must ensure
// they are filled before initialization
this.props.config.rtr = configureRtr(this.props.config.rtr);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reassigning something on props feels icky. Why was it necessary to change this line?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's that, or reassigning the import (configureRtr doesn't change the input). This was changed because my FFetch imported config via stripes-config, whereas before it was passed in.

I can:

  • revert it to being passed in instead, if preferred, but IMO it's best for the shared config to match the filled-in version from configureRtr (and we already do that in render(), where we have gross: this overwrites whatever is currently stored at config.rtr)
  • make configureRtr mutate its input

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are two things happening here with the RTR config:

  1. passing it to FFetch (in the constructor)
  2. passing it Stripes (in render)

As you noted, we can get around (1) by updating FFetch to leverage stripes-config instead, and call configureRtr() in the constructor there. Should we just do the same in render() here? Part of me screams, "You should only have to call that function once! More than once means you're doing it wrong!" The other part of me is like, "Eh, if the value in stripes-config may be sparse, think of configureRtr() as getSafeRtrValues(). Does that still bug ya? No? Great."

Better, worse, just different but not actually better?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Importing stripes-config for render here might make sense, but I'm not familiar enough with the rest of this to know if that's a bad idea.

What we can (and should) do is remove the configureRtr call inside render() here. It just populates the sparse values (as you said), and there's no reason any values should be removed between renders.

Comment on lines 250 to 254
// We only want to configure the event listeners once, not every time
// there is a change to stripes or history. Hence, an empty dependency
// array.
// should `stripes.rtr` go here?
}, []); // eslint-disable-line react-hooks/exhaustive-deps
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably I started with a non-empty array and it didn't work as expected, so I added the empty array as a crutch and never looked back. Your observation/criticism is fair, but I don't have time to debug this further since the only thing "broken" about it is that it can't be modified at runtime via dev-tools.

Copy link

sonarcloud bot commented Oct 11, 2024

@julianladisch julianladisch self-requested a review October 16, 2024 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants