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

Support setting GKs in RecoilEnv #2078

Closed
wants to merge 1 commit into from
Closed

Conversation

impl
Copy link
Contributor

@impl impl commented Oct 24, 2022

In #366 (comment), it was suggested that we could possibly use RecoilEnv to dynamically enable GKs:

Would be interesting if someone wanted to do a PR for mapping GK flags here with the new RecoilEnv.js mechanism to more easily dynamically adjust features without rebuilding..

Well, I wanted to try out the transition support in the same way OP of that issue wanted memory management, so I decided to give the implementation a try: this change adds a new property to RecoilEnv, RECOIL_GKS_ENABLED_UNSTABLE, which can be used to enable certain GKs at runtime. When the property is updated, its changes are proxied to the underlying GK implementation.

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 24, 2022
Copy link
Contributor Author

@impl impl left a comment

Choose a reason for hiding this comment

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

Once y'all are happy with the API, I can push up a docs PR too! :)


export type RecoilEnv = {
RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED: boolean,
RECOIL_GKS_ENABLED_UNSTABLE: string[],
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I made this name _UNSTABLE because I figured the GKs could change over time, but maybe this API itself won't? Not sure if that totally makes sense...

Copy link
Contributor

Choose a reason for hiding this comment

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

Yeah, I would drop the _UNSTABLE here I guess if we are happy with the API. Are you? Maybe call it RECOIL_GKS_ENABLE? Would it also make sense to have a RECOIL_GKS_DISABLE option?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I've been using this patch in my codebase and it suits my needs so I'm happy with it :) I'll rename it to RECOIL_GKS_ENABLE. Regarding adding a ...DISABLE, I think it raises some questions about the semantics of setting the values in that case:

  • If you remove a GK from the ...ENABLE list, does it disable it? Does it add it to ...DISABLE implicitly? (And vice-versa...)
  • If a GK is present in both ...ENABLE and ...DISABLE, which one wins?

I think my preference would be to just leave ...ENABLE and have it be authoritative, i.e. setting it simply changes the list of enabled GKs to whatever it contains.

Thinking out loud, the only thing that's not great then is that environment variable users would need to list all the default GKs if they want to override it. Perhaps when the environment variable is set, we include the default GKs in the list anyway unless the user all provides a magic -defaults value or something? Or we could have two env vars, ...ENABLE and ...REPLACE or something?

Copy link
Contributor

Choose a reason for hiding this comment

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

I was expecting the RECOIL_GKS_ENABLE to act as an override enable for a particular GK if a GK is present in that list. That means no ability to disable a default GK. No need to make things overly complex or add DISABLE at this time unless there's a real need, just trying to think through the ramifications of the API..

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Got it, that makes sense to me. I think in that case we just need to make the list effectively "append-only" so that if we include the default GKs in it they can't be removed. Then we could decide to allow removals in the future if we wanted (or implement a separate ...DISABLE), which would be an API-safe change.

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess an alternative could be instead of trying to enforce append-only or subscribing to changes to update the GKX pass/fail the gkx() wrapper itself could check the environment variable for overrides each time so it's always safe to add/remove enable overrides and the dynamic checks will update at runtime.

// Remove old GKs set in the environment, filter out any GKS that are
// already set by default, and set new GKs.
obj[prop].forEach(gkx.setFail);
obj[prop] = value.filter(gk => !gkx(gk));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is sort of weird because it can potentially remove values from the array before it gets set (so if you check the value after you set it, it might be different than what you set), but it prevents the situation where someone could potentially "enable" and then accidentally disable a built-in enabled GK when they update the property.

Copy link
Contributor

Choose a reason for hiding this comment

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

I'm a little confused why it's necessary to call setFail() for all the enabled GKs here? Wouldn't the following gkx() call then always fail?

Seems the default GKs should also be added to this environment object for introspection.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is basically to work around the default GKs not being present, so if we move it around so that it's in the shared package I don't think it would be necessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

ok, so moving it really sound a lot cleaner then!

const env: RecoilEnv = {
RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED: true,
};
const env: RecoilEnv = new Proxy(
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I couldn't think of a better way to implement this than using a proxy (or moving RecoilEnv into the shared package and having Recoil_gkx reference it, but that seemed like a bigger refactor), but if there is one, I'd be happy to take a suggestion to improve it!

Copy link
Contributor

Choose a reason for hiding this comment

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

This does seem a bit overly complex. Moving to shared would be totally fine. Actually, that would be safer to ensure the GK module is updated before any actual GK checks are made, depending on the order the modules are run.

return;
}

set(sanitizedValue.split(/\s*,\s*/));
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is a comma a good separator for the environment variable?

Copy link
Contributor

Choose a reason for hiding this comment

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

Comma sounds great. But, also allow whitespace as well.

@facebook-github-bot
Copy link
Contributor

@wd-fb has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

@drarmstr
Copy link
Contributor

@impl @wd-fb - Sorry for the delayed review, I was out sick...

@facebook-github-bot
Copy link
Contributor

@impl has updated the pull request. You must reimport the pull request before landing.

@impl
Copy link
Contributor Author

impl commented Nov 1, 2022

OK! I think I've made some progress here. Now gkx() reads directly from RecoilEnv.RECOIL_GKS_ENABLE, so the expected usage would be either:

  1. Set the RECOIL_GKS_ENABLE environment variable to whatever GKs you want enabled, either comma- or space-separated, and they will be added to the list of default GKs.
  2. Add to the RecoilEnv.RECOIL_GKS_ENABLE set in your code before you set up a RecoilRoot, e.g. RecoilEnv.RECOIL_GKS_ENABLE.add('recoil_some_gk');

Let me know what you think!

};

const env: RecoilEnv = {
RECOIL_DUPLICATE_ATOM_KEY_CHECKING_ENABLED: true,
RECOIL_GKS_ENABLE: new Set([
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I noticed this one is present tense but the other existing one is past tense. Maybe this should be RECOIL_GKS_ENABLED after all?

Copy link
Contributor

Choose a reason for hiding this comment

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

makes sense. consistency is good.

This change adds a new property to RecoilEnv, RECOIL_GKS_ENABLED, which
can be used to enable certain GKs at runtime. We update the OSS gkx()
implementation to refer to this property directly, and as a result we
have to move the RecoilEnv to the shared package (which also
conveniently ensures that RecoilEnv properties and gkx() are initialized
together).
@facebook-github-bot
Copy link
Contributor

@impl has updated the pull request. You must reimport the pull request before landing.

@facebook-github-bot
Copy link
Contributor

@wd-fb has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator.

drarmstr pushed a commit to drarmstr/Recoil that referenced this pull request Nov 8, 2022
…#2090)

Summary:
When I run `yarn test`, I got a test case failure from facebookexperimental#2078 that says

```
You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    Recoil/packages/shared/util/__tests__/Recoil_RecoilEnv-test.js:13
    import { IS_INTERNAL } from 'Recoil_TestingUtils';
```
This PR is a fix for that

Pull Request resolved: facebookexperimental#2090

Differential Revision: D41105610

Pulled By: drarmstr

fbshipit-source-id: a3f54b2f7eaf679aee6b9b3505a52ce8217812a5
drarmstr pushed a commit to drarmstr/Recoil that referenced this pull request Nov 8, 2022
…#2090)

Summary:
When I run `yarn test`, I got a test case failure from facebookexperimental#2078 that says

```
You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    Recoil/packages/shared/util/__tests__/Recoil_RecoilEnv-test.js:13
    import { IS_INTERNAL } from 'Recoil_TestingUtils';
```
This PR is a fix for that

Pull Request resolved: facebookexperimental#2090

Differential Revision: D41105610

Pulled By: drarmstr

fbshipit-source-id: 7e55df8ed1257d6548c71716a21ae69d168aa2a6
facebook-github-bot pushed a commit that referenced this pull request Nov 8, 2022
Summary:
When I run `yarn test`, I got a test case failure from #2078 that says

```
You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    Recoil/packages/shared/util/__tests__/Recoil_RecoilEnv-test.js:13
    import { IS_INTERNAL } from 'Recoil_TestingUtils';
```
This PR is a fix for that

Pull Request resolved: #2090

Reviewed By: wd-fb

Differential Revision: D41105610

Pulled By: drarmstr

fbshipit-source-id: 3ef1e854fbe75167d2c4d5289297aa07ebce9611
snipershooter0701 pushed a commit to snipershooter0701/Recoil that referenced this pull request Mar 5, 2023
Summary:
In facebookexperimental/Recoil#366 (comment), it was suggested that we could possibly use `RecoilEnv` to dynamically enable GKs:

> Would be interesting if someone wanted to do a PR for mapping GK flags here with the new `RecoilEnv.js` mechanism to more easily dynamically adjust features without rebuilding..

Well, I wanted to try out the transition support in the same way OP of that issue wanted memory management, so I decided to give the implementation a try: this change adds a new property to `RecoilEnv`, `RECOIL_GKS_ENABLED_UNSTABLE`, which can be used to enable certain GKs at runtime. When the property is updated, its changes are proxied to the underlying GK implementation.

Pull Request resolved: facebookexperimental/Recoil#2078

Test Plan: CI, unit tests

Reviewed By: drarmstr

Differential Revision: D40688490

Pulled By: wd-fb

fbshipit-source-id: 8a748d453e22782c6122a8d5047155019c5d3a1c
snipershooter0701 pushed a commit to snipershooter0701/Recoil that referenced this pull request Mar 5, 2023
Summary:
When I run `yarn test`, I got a test case failure from facebookexperimental/Recoil#2078 that says

```
You'll find more details and examples of these config options in the docs:
    https://jestjs.io/docs/en/configuration.html

    Details:

    Recoil/packages/shared/util/__tests__/Recoil_RecoilEnv-test.js:13
    import { IS_INTERNAL } from 'Recoil_TestingUtils';
```
This PR is a fix for that

Pull Request resolved: facebookexperimental/Recoil#2090

Reviewed By: wd-fb

Differential Revision: D41105610

Pulled By: drarmstr

fbshipit-source-id: 3ef1e854fbe75167d2c4d5289297aa07ebce9611
@impl impl deleted the env-gkx branch May 14, 2023 05:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants