ThreadSafe CallHandler

Topics: Development Team Discussion, User Discussion
Coordinator
Aug 15, 2007 at 6:54 PM
Any issues you see implementing a ThreadSafeCallHandler?

It would intercept calls and wrap call to the next handler into a lock(syncRoot) scope.
Aug 15, 2007 at 10:47 PM
I think the ThreadSafeCallHandler is a good idea, though I believe there would be quite a little implementation details involved.

Some thoughts:
0, Where does syncRoot come from?
->do you have 1 lockobject and have every operation wait for every other operation to complete? that would most definately cause deadlocks
-> do you have 1 per class? (deadlocks when doing recursive calls through PIAB)
-> do you have 1 per instance? where do you store these? locking a random instance of a public type is not a good practice

1. Serializing every method that is called might cause quite some overhead and is unecessary (most of the time)
-> would you serialize only methods that modify state?
-> how would you be able to determine which method modifies state?

I think #0 is something to think through very carefully.
I think #1 would limit the usage scenario's for some, but not cause any real trouble (well, a bit of performance loss at the gain of not having to write your own serialization logic)
Coordinator
Aug 16, 2007 at 4:11 AM
Edited Aug 16, 2007 at 4:12 AM
(new numerotation)
  1. Not sure I understand how 1 instance of syncRoot per class would cause deadlocks for recursive calls since lock reentrancy on a single thread works just fine
-> Meaning if foo1 calls foo2, not sure how deadlock could occur if they share their syncRoot instance.

  1. 1 sync root per instance is what I was heading for, You could even have more than one syncRoot by instance by associating a name the same way a ValidatorAttribute has a RuleSet name.
-> And I would probably store these in some sort of static Dictionary / Cache with WeakRef to the target

  1. In order to specify which method to synchronize, you could use either Sub-Matching rules that are specific to this CallHandler or maybe attributes.

Here's a potential Code snippet:

[ThreadSafeCallHandler]
public class Foo : MBRObject
{
public object Get() { ... }

[ThreadSafe("Sync A")]
public void Set() { ... }
}

Of coure, with interfaces, you'd want to decorate with thread-safetyness using config

Maybe something along those lines:

public interface IFoo
{
object Get();
void Set(...);
}

Config excerpt for Policy X:

<matchingRules>
<add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.TypeMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection" name="Type Matching Rule">
<matches>
<add match="IFoo" ignoreCase="false" />
</matches>
</add>
</matchingRules>
<handlers>
<add type="EnterpriseLibraryContrib.PolicyInjection.CallHandlers.ThreadSafeCallHandler, EntLibContrib.PolicyInjection" name="ThreadSafe Handler">
<matchingRules>
<add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MemberNameMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection" name="Type Matching Rule">
<matches>
<add match="Set" ignoreCase="false" />
</matches>
</add>
</matchingRules>
</add>
</handlers>

Anything is any clearer?
Aug 16, 2007 at 9:36 AM
re: "reentrance on a single thread"

you are right here. this is not an issues.

re: the code example\ configuration?

I wonder what "Sync A" is for? (i do not see it in the configuration).
Is this to identify the lockobject that should be used?

btw - I'd say have a go!
(If you want, i can ask someone with more knowledge about thread sync to review this)
Coordinator
Aug 16, 2007 at 12:48 PM
I definitely will have a go.

On a related subject, if I was able to control creation of call handlers in order to have one instance by target-instance, I could store the syncRoot directly into the CallHandler.

For SyncA, you are right, it was a way to name/identify instances of syncRoot. And you are also right that it wasn't part of the config. Shame on me.