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

Reduce use of globals in SiloProviderRuntime #2485

Merged
merged 1 commit into from Dec 7, 2016

Conversation

ReubenBond
Copy link
Member

@ReubenBond ReubenBond commented Dec 6, 2016

  • Removed SiloProviderRuntime.Instance global
  • Adds a new interface, ISiloRuntimeClient, which contains methods moved from SiloProviderRuntime.
  • GrainCreator now always uses ActivatorUtilities.CreateFactory instead of Activator.CreateInstance, meaning that grain classes with multiple public constructors cannot be constructed unless they are explicitly registered. @jdom are you fine with this? This behavior is consistent with ASP.NET as far as I know.
  • Some methods on SiloProviderRuntime are now forwarded to InsideRuntimeClient where I think they are a more natural fit. We can move them elsewhere if desired.

This is working towards #467. The idea is to make multiple smaller commits to remove globals so that we can implement support for multiple distinct grain clients per AppDomain.

@ReubenBond ReubenBond added this to the 1.4.0 milestone Dec 6, 2016
@jdom
Copy link
Member

jdom commented Dec 6, 2016

GrainCreator now always uses ActivatorUtilities.CreateFactory instead of Activator.CreateInstance, meaning that grain classes with multiple public constructors cannot be constructed unless they are explicitly registered. @jdom are you fine with this? This behavior is consistent with ASP.NET as far as I know

I'm on board, I think is the way to go, but @sergeybykov did push back on this last time as it would be a breaking change

{
services.TryAddSingleton(sp => new GrainCreator(null, sp.GetRequiredService<Func<IGrainRuntime>>()));
}
services.TryAddSingleton<GrainCreator>();
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 trying to understand if this is correct. Today we explicitly pass null as a first argument to new GrainCreator, which triggers it to use Activator.CreateInstance(type) for instantiating grain activations. This will make it always use ActivatorUtilities.CreateFactory(type, Type.EmptyTypes).

Why do we need to change this? Seems unrelated to the stated purpose of the PR.

Copy link
Member Author

Choose a reason for hiding this comment

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

I made a note about this above (you can see @jdom's comment on this PR).
This is needed because some tests require access to things which were previously static but are now no longer exposed in a static manner. Therefore, we inject them into the grains used by the tests. The issue is that under the existing setup, constructor injection is not enabled for grains unless the user specifies a startup class - which is weird because even if we don't actually inject anything in our startup class, it enables dependency injection. It's a violation of the principle of least surprise.

{
get { return appLogger; }
}
public Logger AppLogger => appLogger;
Copy link
Contributor

Choose a reason for hiding this comment

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

In the future, it would help to group such non-essential changes in a separate commit to simplify reviewing. It's pretty easy to do with SourceTree.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep, sorry. I'll shake the habit.

: base(Constants.TypeManagerId, myAddr)
{
if (implicitStreamSubscriberTable == null) throw new ArgumentNullException(nameof(implicitStreamSubscriberTable));
Copy link
Contributor

Choose a reason for hiding this comment

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

A minor thing, but this moved throwing of an ANE to the constructor TypeManager while it used to happen only when GetImplicitStreamSubscriberTable was called. Today this won't break because the table happens to get initialized inside StreamingInitialize() before TypeManager is instantiated. But this may easily break in the future if we rearrange things or make some of the streaming components pluggable and maybe even optional.

Copy link
Member Author

Choose a reason for hiding this comment

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

That's true. The NRE is not really needed here. The value won't be null even if it hasn't yet been initialized - DI is used to construct ImplicitStreamSubscriberTable and then TypeManager is constructed using it inside Silo.CreateSystemTargets like so:

var implicitStreamSubscriberTable = Services.GetRequiredService<ImplicitStreamSubscriberTable>();
this.RegisterSystemTarget(new TypeManager(this.SiloAddress, this.typeManager, implicitStreamSubscriberTable));

Currently, it's initialized in Silo.DoStart before the call to CreateSystemTargets,
On the client side, it's initialized by calling into the gateway (which hits the TypeManager system target).

So I believe this is sound

Copy link
Member Author

Choose a reason for hiding this comment

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

In the latest revision, you'll see that this aligns to what Ben is doing since his heterogenous silos PR

@sergeybykov sergeybykov self-assigned this Dec 7, 2016
@ReubenBond ReubenBond force-pushed the statics-removal branch 2 times, most recently from 21c90ee to 55cc148 Compare December 7, 2016 01:29
@@ -820,5 +790,89 @@ public void BreakOutstandingMessagesToDeadSilo(SiloAddress deadSilo)
}
}
}

public StreamDirectory GetStreamDirectory()
{
Copy link
Member Author

Choose a reason for hiding this comment

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

These are originally from SiloProviderRuntime

@ReubenBond
Copy link
Member Author

ReubenBond commented Dec 7, 2016

Addressed all feedback, functionals should all be passing - 2 were failing for the same reason (multiple constructors), but they're fixed.

EDIT: btw, I undid most of the superfluous/stylistic changes you pointed out @sergeybykov

@sergeybykov
Copy link
Contributor

EDIT: btw, I undid most of the superfluous/stylistic changes you pointed out @sergeybykov

Oh, sorry, I didn't mean to revert them. Cleanup changes like that are good. It's just easier to review when such changes are in a separate commit. If you still have them around and can easily submit, please do.

@sergeybykov sergeybykov merged commit bdc2cb2 into dotnet:master Dec 7, 2016
@ReubenBond ReubenBond deleted the statics-removal branch December 7, 2016 18:41
@github-actions github-actions bot locked and limited conversation to collaborators Dec 11, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants