Synchronisation of managed instances - multithreading

I want to implement a sort of multiton class (maybe also know as a Manager Design Pattern) that loads (and manages) objects according to user configuration (the key of each object in the multiton is the primary key of the configuration record). These objects are disposed and recreated (i.e. reloaded) if changes in configuration is detected.
Other objects (external to the managed objects) interacts/communicates with these "managed" objects.
E.g.
ManagerA manages instances of configured instances of ClassA.
ObjectB retrieves an instance of ClassA via ManagerA and starts
interacting with the instance.
The problem is that the interaction between ObjectB and the managed instance of ClassA can potentially be on another thread than on which the ManagerA disposes the instance of ClassA and creates a new instance of ClassA (for the new changed configuration). I.e. the managed instance could be disposed just as (or just before) interaction with the managed object.
My question is how should one synchronise the instance management and interaction with these managed instances by external objects?

This is pretty difficult with no code, psuedo code, or such provided but...
If the client interacts with the managed protocol objects by enqueuing actions, and that queue of actions is longer-lived the the managed protocol object, perhaps it would be better to seperate that queue from the managed protocol and just pass a reference to the queue-like object to the client.
When something is enqueued, have your queue-like object check out a properly configured protocol object and use it. I assume that while it is in use (meaning bytes are flying across the wire) it cannot be changed/configured. After that one action has been completed, have the queue-like object then check the protocol object back in to your manager. Upon checkin, if the manager has detected changes in the configuration it can dispose and recreate the protocol object, and if not then it is still sitting there ready to go for next use. If upon detection of configuration change the object is not currently checked out, that recreation step can happen immediately.
The client is shielded from these details because it never access the protocol object directly. (Though if that was a requirement then you could still apply a check-in and check-out concept to the protocol objects to make sure they are up to date, but it is harder to enforce since the client can forget to do the check in and re-checkout).

Related

Hazelcast and the need for custom serializers; works when creating the server but not when connecting to existing

We are using Hazelcast to store stuff in distributed maps. We are having a problem with remote servers and I need some feedback on what we can do to resolve the issue.
We create the server - WORKS
We create a new server (Hazelcast.newHazelcastInstance) inside our application's JVM. The hazelcast Config object we pass in has a bunch of custom serializers defined for all the types we are going to put in the maps. Our objects are a mixture of Protobufs, plain java objects, and a combination of the two. The server starts, we can put objects in the map and get objects back out later. We recently decided to start running Hazelcast in its own dedicated server so we tried the scenario below.
Server already exists externally, we connect as a client - DOESN'T WORK
Rather than creating our Hazelcast instance we connect to a remote instance that is already running. We pass in a config with all the same serializers we used before. We successfully connect to Hazelcast and we can put stuff in the map (works as far as I can tell) but we don't get anything back out. No events get fired letting our listeners know objects were added to a map.
I want to be able to connect to a Hazelcast instance that is already running outside of our JVM. It is not working for our use case and I am not sure how it is supposed to work.
Does the JVM running Hazelcast externally need in its class loader all of the class types we might put into the map? It seems like that might be where the problem is but wouldn't that make it very limiting to use Hazelcast?
How do you typically manage those class loader issues?
Assuming the above is true, is there a way to tell Hazelcast we will serialize the objects before even putting them in the map? Basically we would give Hazelcast an ID and byte array and that is all we would expect back in return. If so that would avoid the entire class loader issue I think we are running into. We do not need to be able to search on objects based on their fields. We just need to know as objects come and go and what their ID is.
#Jonathan, when using client-server architecture, unless you use queries or other operations that require data to be serialized on the cluster, members don't need to know anything about serialization. They just store already serialized data & serve it. If these listeners that you mentioned are on the client app, it should be working fine.
Hazelcast has a feature called User Code Deployment, https://docs.hazelcast.org/docs/3.11/manual/html-single/index.html#member-user-code-deployment-beta, but it's mainly for user classes. Serialization related config should be present on members or you should add that later & do a rolling restart.
If you can share some of the exceptions/setup etc, I can give specific answers as well.

Preventing duplicate entries in Multi Instance Application Environment

I am writing an application to serve facebook APIs; share, like etc.. I am keeping all those shared objects from my appliction in a database and I do not want to share the same object if it already been shared.
Considering I will deploy application on different servers there could be a case where both instance tries to insert the same object to table.
How can I manage this concurrency problem with blocking the applications fully ? I mean two threads will try to insert same object and they must sync but they should not block a 3rd thread where it is inserting totally different object.
If there's a way to derive primary key of data entry from data itself, database will resolve such concurrency issue by itself -- 2nd insert will fail with 'Primary Key constraint violation'. Perhaps, data supplied by Facebook API already have some unique ID?
Or, you can consider some distributed lock solution, for example, based on Hazelcast or on similar data grid. This would allow to have record state shared by different JVMs, so it will be possible to avoid unneeded INSERTS.

Is the Azure Table Client for .NET Threadsafe?

Can I just have one global instance of the client and table, or do I need a separate instance per thread?
reference: https://msdn.microsoft.com/en-us/library/azure/microsoft.windowsazure.storage.table.aspx
Each individual class should describe whether it is thread-safe or not. I know some are. I suspect some are not.
Example: CloudTable's public static methods are thread-safe but instances of the class are not.
More than likely, you'll want multiple instances of these. If you have some strange scaling issue where this is problematic, consider creating a "ClientPool" somewhat akin to a Connection Pool to lease and reuse instances.

ColdFusion singleton object pool

In our ColdFusion application we have stateless model objects.
All the data I want I can get with one method call (it calls other internally without saving the state).
Methods usually ask the database for the data. All methods are read only, so I don't have to worry about thread safety (please correct me if I'm wrong).
So there is no need to instantiate objects at all. I could call them statically, but ColdFusion doesn't have static methods - calling the method would mean instantiating the object first.
To improve performance I have created singletons for every Model object.
So far it works great - each object is created once and then accessed as needed.
Now my worry is that all requests for data would go through only 1 model object.
Should I? I mean if on my object I have a method getOfferData() and it's time-consuming.
What if a couple of clients want to access it?
Will second one wait for the first request to finish or is it executed in a separate thread?
It's the same object after all.
Should I implement some kind of object pool for this?
The singleton pattern you are using won't cause the problem you are describing. If getOfferData() is still running when another call to that function gets called on a different request then this will not cause it to queue unless you do one of the following:-
Use cflock to grant an exclusive lock
Get queueing connecting to your database because of locking / transactions
You have too many things running and you use all the available concurrent threads available to ColdFusion
So the way you are going about it is fine.
Hope that helps.

WCF NetTCP with Background Threading

Background:
I have a system that hosts WCF services inside a Windows Service with NetTCP binding. To add a new service to the collection you simply add the standard WCF config entries inside <system.serviceModel -> services /> and then add a line inside a custom configuration section that tells the hosting framework it needs to initialize the service. Each service is initialized with its own background thread and AppDomain instance to keep everything isolated.
Here is an example of how the services are initialized:
Host
- ServerManager
- ServiceManager
- BaseServerHost
The ServerManager instance has a collection of ServiceManagers that each correlate to a single service instance which is where the standard WCF implementation lies (ServiceHost.Open/Close, etc). The ServiceManager instance instantiates (based on the config - it has the standard assembly/type definition) an instance of the service by use of the BaseServerHost base class (abstract). Every service must inherit from this for the framework to be able to use it. As part of the initialization process BaseServerHost exposes a couple of events, specifically an UnhandledException event that the owning ServiceManager attaches itself to. (This part is critical in relation to the question below.)
This entire process works exceptionally well for us (one instance is running 63 services) as I can bring someone on who doesn't know anything about WCF and they can create services very quickly.
Question:
The problem I have run into is with background threading. A majority of the exposed methods on our endpoints do a significant amount of activity after a standard insert/update/delete method call such as sending messages to other systems. To keep performance up (the front-end is web-based) we let the initial insert/update/delete method do its thing and then fire off a background thread to handle all the stuff an end-user doesn't need to wait for to complete. This option works great until something in that background thread goes unhandled and brings the entire Windows service down, which I understand is by design (and I'm OK with).
Based on all of my research I have found that there is no way to implement a global try/catch (minus using the hacked config of enabling 1.1 handling of background crashing) so my team will have to go back and get those in the appropriate places. That aside, what I've found is on the endpoint side of the WCF hosting appears to be in its own thread on each call and getting that thread to talk to the "parent" has been a nightmare. From the service viewpoint here is the layout:
Endpoint (svc - inherits from BaseServerHost, mentioned above)
- Business Layer
- Data Layer
When I catch an exception on a background thread in the business layer I bubble it up to the Endpoint instance (which inherits from BaseServerHost) which then attempts to fire BaseServerHost's UnhandledException event for this particular service (which was attached to by the owning ServiceManager that instantiated it). Unfortunately the event handler is no longer there so it does nothing at all. I've tried numerous things to get this to work and thus far all of my efforts have been in vain.
When looking at the full model (shown below), I need to make the Business layer know about its parent Endpoint (this works) and the endpoint needs to know about the running BaseServerHost instance which needs to know about the ServiceManager that is hosting it so the errors can be bubbled up to this for use in our standard logging procedures.
Host
- ServerManager
- ServiceManager <=====================
- BaseServerHost ||
- Endpoint (svc) ||
- Business Layer <======
- Data Layer
I've tried static classes with no luck and even went as far as making ServerManager static and expoting its previously internal collection of ServiceManagers (so they can be shutdown), but that collection is always empty or null too.
Thoughts on making this work?
EDIT: After digging a little further I found an example of exactly how I envision this working. In a standard ASP.NET website, on any page/handler etc. you can use the HttpContext.Current property to access the current context for that request. This is exactly how I would want this to work with a "ServiceManager.Current" returning the owning ServiceManager for that service. Perhaps that helps?
Maybe you should look into doing something with CallContext:
http://msdn.microsoft.com/en-us/library/system.runtime.remoting.messaging.callcontext.aspx
You can use either SetData/GetData or LogicalSetData/LogicalGetData, depending on whether you want your ServiceManager to be associated with one physical thread (SetData) or a "logical" thread (LogicalSetData). With LogicalSetData you could make the same ServiceManager instance available within a thread as well as within that thread's "child" threads. Will try to post a couple of potentially useful links later when I can find them.
Here is a link to the "Virtual Singleton Pattern" on codeproject.
Here is a link to "Thread Singleton"
Here is a link to "Ambient Context"
All of these ideas are similar. Essentially, you have an object with a static Current property (can be get or get/set). Current puts its value in (and gets it from) the CallContext using either SetData (to associate the "Current" value with the current thread) or LogicalSetData (to associate the "Current" value with the current thread and to flow the value to any "child" threads).
HttpContext is implemented in a similar fashion.
System.Diagnostics.CorrelationManager is another good example that is implemented in a similar fashion.
I think the Ambient Context article does a pretty good job of explaining what you can accomplish with this idea.
Whenever I dicsuss CallContext, I try to also include this link to this entry from Jeffrey Richter's blog.
Ultimately, I'm not sure if any of this will help you or not. One it would be useful would be if you had a multithreaded server application (maybe each request is fulfilled by a thread and multiple requests can be fulfilled at the same time on different threads), you might have a ServiceManager per thread. In that case, you could have a static Current method on ServiceManager that would always return the correct ServiceManager instance for a particular thread because it stores the ServiceManager in the CallContext. Something like this:
public class ServiceManager
{
static string serviceManagerSlot = "ServiceManager";
public static ServiceManager Current
{
get
{
ServiceManager sm = null;
object o = CallContext.GetData(serviceManagerSlot);
if (o == null)
{
o = new ServiceManager();
CallContext.SetData(serviceManagerSlot, o);
}
sm = (ServiceManager)o;
return sm;
}
set
{
CallContext.SetData(serviceManagerSlot, value);
}
}
}
Early in your process, you might configure a ServiceManager for use in the current thread (or current "logical" thread) and then store in the "Current" property:
ServiceManager sm = new ServiceManager(thread specific properties?);
ServiceManager.Current = sm;
Now, whenever you retrieve ServiceManager.Current in your code, it will be the correct ServiceManager for the thread in which you are current executing.
This whole idea might not really be what you want.
From your comment you say that the CallContext data that you try to retrieve in the event of an exception is null. That probably means that exception is being raised and/or caught on a different thread than the thread on which the CallContext data was set. You might try using LogicalSetData to see if that helps.
As I said, I don't know if any of this will help you, but hopefully I have been clear enough (and the examples have also been clear enough) so you can tell if these ideas apply to your situation or not.
Good luck.

Resources