Skip to content

Investigation on supporting module isolation #164

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

Merged
merged 6 commits into from
Aug 12, 2019

Conversation

daxian-dbw
Copy link
Member

@daxian-dbw daxian-dbw commented Mar 27, 2019

Note: This RFC focuses on the module-level isolation, but it's written with the purpose to be withdrawn.
While researching the feasibility of this idea, I realized that it's impossible to have it well supported due to the challenges discussed below.
This RFC serves as a summary of the research to explain the reasons why we will not proceed with this idea.

In the Alternate Proposals and Considerations section, I briefly discuss the Runspace-level isolation and using AssemblyLoadContext.Default.Resolving to solve the problem of conflicting NewtonSoft.Json assembly.
I think Runspace-level isolation is more promising and useful. I can write another RFC about how to support Runspace-level isolation in PowerShell.

@daxian-dbw daxian-dbw requested a review from SteveL-MSFT March 27, 2019 03:52

### Import-Module -Isolated

The idea is simple: Add the switch parameter `-Isolated` to `Import-Module`.
Copy link
Member

Choose a reason for hiding this comment

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

Regardless of how we implement this, I don't think we can require the user to use a switch to specify isolation. The majority of users won't understand why this is needed nor when to use it. Only in developer scenarios would such a switch make sense. For regular users, it needs to be transparent.

Copy link
Member Author

@daxian-dbw daxian-dbw Mar 27, 2019

Choose a reason for hiding this comment

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

For regular users, it needs to be transparent.

That makes sense, and I think AssemblyLoadContext.AssemblyResolve event might be a better fit for solving the conflicting NewtonSoft.Json issue, in a transparent way (see the second section in the Alternative Considerations).
As for the module isolation, it won't work. The introduced type identity issue will make it impossible to be transparent to the user.

@iSazonov
Copy link
Contributor

iSazonov commented Apr 2, 2019

We could split the area on two parts:

  • a module exports types from an problematic assembly
  • a module doesn't export types from an problematic assembly

In second case it seems we could easily resolve the problem internally in the module. It doesn’t even require any changes to the engine - only documentation. Although we could add some API for developers to create code (ALC) in one standard.

Related question. CoreFX can also load assemblies (NewtonSoft too!) - and it is not clear can we change the CoreFX context or not.

As for first case. It looks like a dialectic - we want isolation, but we want everything in global! :-) So what do we want? I believe that isolation from global is implied.

Module term assumes an isolation. Even if we accept this RFC with description why it does not work it will always continue to amaze and will look like an unpleasant limitation of the language.
Perhaps we could introduce new closure (PowerShell+Runspace+Scope) (microservice? :-) ) without intersection with global and have there nearly full isolation - new ALC, new type cache - with only one bridge for PSCustomObjects (and maybe with a subset of CoreFX standard objects). We might even safely destroy the closure along with ALC.

@daxian-dbw
Copy link
Member Author

a module doesn't export types from an problematic assembly

Not exactly sure about what you mean by export types. Type resolution may happen in the module's psm1 file, a user could do anything they want within the module scope by & $moduleInfo { ... }.
There is simply no way to make this feature transparent to the user -- a user needs to know how this feature work to use this feature and otherwise she/he may run into very confusing errors.

Module term assumes an isolation.

The term Module here is a PowerShell concept. It offer isolation within the PowerShell context. When it comes to the assembly level, even CLR doesn't grant you the isolation by default. You need to do it explicitly in dotnet application.
As the RFC discussed in the Alternative Consideration section, Runspace is a more feasible isolation boundary for PowerShell.

@joeyaiello joeyaiello merged commit ce441e0 into PowerShell:master Aug 12, 2019
@daxian-dbw daxian-dbw deleted the module-isolation branch August 12, 2019 19:25
If it's a module with a custom load context, then the type resolution will search assemblies from the custom-ALC and then the default-ALC to find the `TypeName`.
Otherwise, the type resolution will search the default-ALC only.

So in the above imagined scenario, it's possible to make it work as expected if you construct the object using `[M\B::C]` from the default-ALC.
Copy link
Contributor

Choose a reason for hiding this comment

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

We could use [M::B::C]. Using \ is Windows style and we will have to consider /. Although with :: we could get difficulties in parser with provider form.

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