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

chore(databases-collection): refactor create db / create coll to a single create namespace plugin COMPASS-7410 #5100

Merged
merged 6 commits into from
Nov 14, 2023

Conversation

gribnoysup
Copy link
Collaborator

@gribnoysup gribnoysup commented Nov 10, 2023

Last follow-up to #5085

  • Merges create database and create collection plugin into a single create namespace plugin
  • Store is updated to typescript, but all existing logic is preserved with minimal changes
  • Plugin is using service injectors for everything, including the new instance locator

@@ -3,7 +3,7 @@ import { createContext, useContext } from 'react';

export const InstanceContext = createContext<MongoDBInstance | null>(null);

export const useMongoDBInstance = (): MongoDBInstance => {
export const mongoDBInstanceLocator = (): MongoDBInstance => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@addaleax don't know if you have a strong preference here, I thought that I'd rename it to match other methods we have and to indicate a bit better that it's not supposed to be used as a hook in React (even though it sorta is).

I think if we want to add actual hooks here (should be very valuable in some cases!), those should probably be a bit more high level, encapsulating the model subscription logic for a required field internally instead of just exposing the modal to the React view 🤔

Copy link
Collaborator

Choose a reason for hiding this comment

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

sure, no strong preferences here! happy to stick to whatever pattern we choose 🙂

@@ -100,6 +100,7 @@ declare class MongoDBInstance extends MongoDBInstanceProps {
}): Promise<Collection | null>;
removeAllListeners(): void;
on(evt: string, fn: (...args: any) => void);
off(evt: string, fn: (...args: any) => void);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Collaborator

Choose a reason for hiding this comment

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

ah actually, now I remember why I did this; AppRegistry has removeListener but not off. Should we also add off to AppRegistry then?

Copy link
Collaborator Author

@gribnoysup gribnoysup Nov 13, 2023

Choose a reason for hiding this comment

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

We can do that for consistency, yes, especially now that we use it so much! With ampersand models you have off, but not removeListener, so this is why I added it here and it'd be harder for us to extend ampersand models to support removeListener compared to doing this for app registry 🙂

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ahh, wait, I think I'm just silly, I'm sure I got "can't call undefined error" when trying removeListener, but it's definitely there. Will update!

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Renamed to align with your PR in 6691588

@gribnoysup gribnoysup marked this pull request as ready for review November 13, 2023 11:12
@gribnoysup
Copy link
Collaborator Author

Added tests, should be ready for review now

Comment on lines +96 to +113
/**
* Convenience method for testing: allows to override services and app
* registries available in the plugin context
*
* @example
* const PluginWithLogger = registerHadronPlugin({ ... }, { logger: loggerLocator });
*
* const MockPlugin = PluginWithLogger.withMockServices({ logger: Sinon.stub() });
*
* @param mocks Overrides for the services locator values and registries
* passed to the plugin in runtime. When `globalAppRegistry`
* override is passed, it will be also used for the
* localAppRegistry override unless `localAppRegistry` is also
* explicitly passed as a mock service.
*/
withMockServices(
mocks: Partial<Registries & Services<S>>
): React.FunctionComponent<T>;
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@addaleax this is this new testing helper I mentioned, I also switched drop-namespace tests to use it too (although due to how this particular plugin works, it doesn't make that much of a difference in that case)

return [s, mockServices[s] ? () => mockServices[s] : services?.[s]];
})
) as unknown as S;
const MockPlugin = registerHadronPlugin(config, mockServiceLocators);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Won’t it be an issue that this re-uses the same registryName as the original plugin and therefore shares a store (which may have already been initialized with the original services)?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Hmmm, I think for that to conflict you'd need to actually render / activate both mocked and unmocked plugin in the same test, which sounds like a rare corner case, unless I'm missing some scenario here 🤔 Doesn't hurt to override config name here though, generally not that we should rely on it in any way externally, can do that!

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just needs to happen in the same process as long as the global app registry is truly global, right? That doesn’t seem all that unlikely, and it’s going to be hard to diagnose because it could involve some “spooky action at a distance” from a completely unrelated test that also happens to render the plugin.

Another approach, maybe even a better one, would be figuring out how to best avoid having a truly global globalAppRegistry in tests at all. Ideally, tests should probably use a distinct one each time, not share the same on across all tests in that process…?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, I see what you mean. Then I think we can change the code there that passes globalAppRegistry value to the context to be _globalAppRegistry ?? new AppRegistry(): if you don't care about the reigstry or don't need to interact with it inside the actual test, this would be just a safe fallback, but if you want to emit events or something, then you'd want to pass your instance there. How does that sound?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah, I think that makes for some nice isolation between tests, and it should be easy enough to work around if it we do want the actual global instance?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Totally, and it would be super explicit if you want to pass the global one, it's a singleton export from the app-registry package. Will update, thanks for the feedback!

Copy link
Collaborator Author

@gribnoysup gribnoysup Nov 13, 2023

Choose a reason for hiding this comment

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

Updated globalAppRegistry to be always scoped as discussed in 72c9c15. Also when doing that stumbled on something that I think is a bug: we did call plugin.deactivate in appRegistry.deactivate, but didn't de-register plugins, changed that too to always clean-up plugins from registry as at the moment we call deactivate there, we expect this whole thing to be disposeable basically

@gribnoysup gribnoysup merged commit cbb9d01 into main Nov 14, 2023
5 checks passed
@gribnoysup gribnoysup deleted the compass-7410-create-namespace branch November 14, 2023 08:35
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.

2 participants