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

Sni/lock free #45

Merged
merged 1 commit into from May 10, 2016
Merged

Sni/lock free #45

merged 1 commit into from May 10, 2016

Conversation

stephanenicolas
Copy link
Owner

@stephanenicolas stephanenicolas commented May 1, 2016

DO NOT MERGE

Besides Daniel, I would love Michael & Henri to review this.
The goal of this PR is to

  • make TP crash free in a multi threading context. It appears that we have been making a few mistakes on this since the beginning.
  • pass tests that heavily use the data structure (scope tree) concurrently
  • make TP lock free. Each injection will see a snapshot of TP scope tree, before or after any modification but not in between. This makes the most normal usages of TP much faster.

This version provides an improvement for massive DI :

image

For 55 K injections.

@coveralls
Copy link

Coverage Status

Coverage decreased (-10.6%) to 75.014% when pulling 287b4ec on sni/lock-free into c46f936 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-10.7%) to 74.942% when pulling 287b4ec on sni/lock-free into c46f936 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-10.5%) to 75.115% when pulling 287b4ec on sni/lock-free into c46f936 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-10.5%) to 75.115% when pulling 74a2fda5baefed77802f3d35575d5a2e4e26264e on sni/lock-free into c46f936 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-10.8%) to 74.799% when pulling 66b9306 on sni/lock-free into c46f936 on master.

}
removeScopeAndChildrenFromMap(scope);

public static synchronized void closeScope(Object name) {
Copy link

Choose a reason for hiding this comment

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

do you still need synchronized here? or only synchronized when scope != null

Copy link

Choose a reason for hiding this comment

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

why openScope() is not synchronized and closeScope() is?

@coveralls
Copy link

Coverage Status

Coverage decreased (-11.0%) to 74.627% when pulling b9e11dc on sni/lock-free into c46f936 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-11.0%) to 74.627% when pulling f899768 on sni/lock-free into c46f936 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-10.9%) to 74.669% when pulling 8784b2fbbaea03be11f503754062251374015b99 on sni/lock-free into c46f936 on master.

MAP_KEY_TO_SCOPE.put(name, scope);
}
Scope scope = MAP_KEY_TO_SCOPE.get(name);
if (scope != null) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

We have:
... A
../ ...
B.....C

And then:

  1. Thread 1 calls -> closeScope(A)
  2. Thread 2 calls -> openScope(C)

Thread 2 can get scope C when it is about to be removed. Should we allow that?

Copy link
Owner Author

Choose a reason for hiding this comment

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

yes, t2 should get something. The idea of the lock free structures is that when a thread reads and another thread writes, the reader sees the data structure either before or after the change, but not during the transition. And I believe it's the case here. In a multi-threaded context, you should be careful that your scope was not closed before using it.

Closing a scope will detach it from the tree, and C will become a root of a new tree indeed. With synchronized, the exact same problem will happen a millisecond later if some thread closes the scope you just opened.

My point of view is that this can be more or less adressed by DI itself. In Android for instance, the main thread starts a background threads with a callback, when the main thread leaves the context, it should remove the callback and interrupt the background thread or not. If the background thread uses only the application level scope, it can be allowed to continue will the activity is dead, but if it uses activity scope or lower, it should be stopped.

So in one case, you can use the scope, in the other not. Really, I don't think this can be fully solved by DI. What I favored here is performance.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.3%) to 84.989% when pulling b374d17 on sni/lock-free into 3f70ec5 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.3%) to 84.989% when pulling b374d17 on sni/lock-free into 3f70ec5 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.4%) to 84.873% when pulling d8d7c1861f7199c720ef68d44d919b091ee73fc8 on sni/lock-free into 3f70ec5 on master.

@coveralls
Copy link

Coverage Status

Coverage decreased (-0.4%) to 84.81% when pulling 2f5684dfb34a68a16f327c89ed10ec21ef3b991b on sni/lock-free into 3f70ec5 on master.

@stephanenicolas
Copy link
Owner Author

stephanenicolas commented May 7, 2016

Only coveralls fails (-0.4%) but build passes.
Ready for review. :)

public synchronized InternalProviderImpl<? extends T> getProvider(String bindingName) {
InternalProviderImpl<? extends T> internalProvider = mapNameToProvider.get(bindingName);
return internalProvider;
public InternalProviderImpl<? extends T> getProvider(String bindingName) {
Copy link

Choose a reason for hiding this comment

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

@coveralls
Copy link

Coverage Status

Coverage decreased (-3.6%) to 89.019% when pulling 5ba7feb on sni/lock-free into 16ab592 on master.

@stephanenicolas stephanenicolas merged commit db3590c into master May 10, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants