Does COM provide methods to delay shutdown until all RPCs are done? - com

I have two processes: a Client and a Server. Client makes a call that the Server starts processing, but the Server can start shutting down before the call is finished. This can cause objects required by the call to suddenly become destroyed, leading to a crash.
The Client and Server communicate through COM. Something that tells the amount of currently active RPCs from and to a given Server process would be extremely helpful in this case.
Does COM, as the layer of communication between these two processes, provide any aid in delaying shutdown when there is active interaction them?

I don't know which langage has been used to implement your COM client/server.
But as far as I understand, it looks like you are facing a COM multithreading issue. What is the threading model of your COM server? (I suppose it multithreaded)
If it's the case, you should synchronize your threads.
The over way would be to transform the threading model of your COM server into a single threaded model. In that case, server shutting down call will be executed after previous client call finishes.

I suspect you really want CoAddRefServerProcess inside your C++ object's constructor (and CoReleaseServerProcess in the destructor).
This will keep your server alive until the C++ objects go away.
However, this won't prevent the client from requesting new instances, so you may also want:
CoRevokeClassObject to prevent new instances of the client from obtaining proxies.
If you're feeling really nasty, CoDisconnectObject will forcibly disconnect the proxy from the server.
*

Related

Reuse WCF server instance between operations, without concurrency

How can I make the WCF server instance (the instance of the class in the .svc.cs / .svc.vb file) stay alive between requests?
It's a stateless, read-only type of service: I'm fine with different clients reusing the same instance. However, it's not thread-safe: I don't want two threads to execute a method on this instance concurrently.
Ideally, what I'm looking for is that WCF manages a "worker pool" of these instances. Say, 10. New request comes in: fetch an instance, handle the request. Request over, go back to the pool. Already 10 concurrent requests running? Pause the 11th until a new worker is free.
What I /don't/ want is per-client sessions. Startup for these instances is expensive, I don't want to do that every time a new client connects.
Another thing I don't want: dealing with this client-side. This is not the responsibility of the client, which should know nothing about the implementation of the server. And I can't always control that.
I'm getting a bit lost in unfamiliar terminology from the MSDN docs. I have a lot working, but this pool system I just can't seem to get right.
Do I have to create a static pool and manage it myself?
Thanks
PS: A source of confusion for me is that almost anything in this regard points toward the configuration of the bindings. Like basicHttp or wsHttp. But that doesn't sound right: this should be on a higher level, unrelated to the binding: this is about the worker managers. Or not?
In the event that you have a WCF service that centralizes business logic, provides/controls access to another “single” backend resource (e.g. data file, network socket) or otherwise contains some type of shared resource, then you most likely need to implement a singleton.
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
In general, use a singleton object if it maps well to a natural singleton in the application domain. A singleton implies the singleton has some valuable state that you want to share across multiple clients. The problem is that when multiple clients connect to the singleton, they may all do so concurrently on multiple worker threads. The singleton must synchronize access to its state to avoid state corruption. This in turn means that only one client at a time can access the singleton. This may degrade responsiveness and availability to the point that the singleton is unusable as the system grows.
The singleton service is the ultimate shareable service, which has both pros(as indicated above) and cons (as implied in your question, you have to manage thread safety). When a service is configured as a singleton, all clients get connected to the same single well-known instance independently of each other, regardless of which endpoint of the service they connect to. The singleton service lives forever, and is only disposed of once the host shuts down. The singleton is created exactly once when the host is created.
https://msdn.microsoft.com/en-us/magazine/cc163590.aspx

Is there a way to pass arbitrary struct via XPC?

I would like my Cocoa app to communicate with a database server. Following the principle in the app sandbox design, it would make sense for the DB communications to be split out into an XPC service.
Since an XPC service is supposed to be stateless, the struct containing the connection info (eg. a MySQL connection handle) would need to be held by the main app and passed into the XPC service as needed. However the handle is an opaque type which does not appear to be supported by XPC services - only basic arithmetic/logic/collection types are allowed.
Is there some way to box a connection handle (or other opaque type) such that it can be passed to an XPC service?
Since a MySQL connection handle isn't stateless, and because the whole point of isolating the network code into an XPC in the first place is stability, I wouldn't worry about the statelessness. It is considered preferable, but it isn't a requirement. To quote:
Because an XPC service can be terminated suddenly at any time, it must be designed
to hold on to minimal state—ideally, your service should be completely stateless,
although this is not always possible.
XPC documentation
This is one of those cases where it isn't always possible. The MySQL connection holds state of its own, so if you want to remain stateless, your best bet would be to pass all of your credentials to the XPC as an atomic operation each time, and that's going to be inefficient.
Instead, I'd suggest that you create some kind of "handle" passed back and forth between your app and the XPC which can be looked up in a table within the XPC for validation (that way if the XPC is terminated and started again it can tell that it was interrupted and send an error back). Then, on the application side, you can send that handle for operations and have your internal API handle re-opening if appropriate by re-acquiring the "handle" from the XPC when necessary. This could be done directly in your code which makes the database calls, but if the XPC is prone to death, then you would want to put it into an internal library and maintain the credentials so that you could restart the XPC and re-initaite the connection without bothering the higher-level code.
Either way, you're going to want to keep calls to the XPC at an SQL transaction level, because the MySQL connection could abort between calls to the XPC, and that would cause a roll-back and you'd have to start over.

Out of process COM server with MTA

I have an out of proc COM (ATL) Server that has been created as free threaded (CComMultiThreadModel)
I am slightly confused as to how that relates to the re-entrancy of calls into my object, for example I assumed that I would be allowed to call from multiple clients simultaneously and have those requests processed simultaneously however it seems (according to my logs) that each request is serialized.
What am I missing, does simply creating a class as MTA mean it truly is or is there something else I have to do. Note that I am referring here to multiple processes all making concurrent calls and not threads within a single process and thus COINIT_MULTITHREADED is not the problem.
This snippet from some MS documentation on MTA would seem everything should work out of the box:
Multiple clients can simultaneously call, from different threads, an object that supports free-threading. In free-threaded out-of-process servers, COM, through the RPC subsystem, creates a pool of threads in the server process and a client call (or multiple client calls) can be delivered by any of these threads at any time
No sooner than I asked it I found the answer, you need to specify #define _ATL_FREE_THREADED in stdafx.h

In COM, how can I get notified when a client dies?

I've got a COM solution with a client (an EXE) and a server (a service EXE). When the client is killed, or dies abnormally, I'd like to know about it in the server. Unfortunately, it appears that COM doesn't call Release when this happens.
How can I tell that a COM client has died, so that I can clean up for it?
Update: Answers so far require that the server have a pointer to the client, and call a method on it periodically (ping). I'd rather not do this, because:
I don't currently have a callback pointer (server->client), and I'd prefer to avoid introducing one, unless I really have to.
This still won't call Release on the object that represents the client endpoint, which means that I'll have to maintain the other client-specific resources separately, and hold a weak pointer from the "endpoint" to the other resources. I can't really call Release myself, in case COM decides to do it later.
Further to the second: Is there any way, in COM, to kill the client stub, in lieu of calling Release? Can I get hold of the stub manager for my object and interface and tell it to do cleanup?
Killing is rather extremal process, so neither CORBA, nor COM/DCOM nor Java's RMI has no explicit work around. Instead you can create very simple callback to implement 'ping'. It can be for example time based or on occasional base.
Also you can think about third EXE - that works as monitor for your client and provides notification to server (a service).
Simplest solution is for the server to run a PING test on a timer.
In a multi threaded apartment setup this can run on a background thread.
This test should call from server to client with a call that's guaranteed to make it to the client if it is alive e.g. a QueryInterface call on a client object.
Unexpected failures can be treated as an indication that the client is dead.
The server will need to manage the list of clients it pings intelligently and should ensure that the ping logic itself doesn't keep the client alive.

WCF Server Push connectivity test. Ping()?

Using techniques as hinted at in:
http://msdn.microsoft.com/en-us/library/system.servicemodel.servicecontractattribute.callbackcontract.aspx
I am implementing a ServerPush setup for my API to get realtime notifications from a server of events (no polling). Basically, the Server has a RegisterMe() and UnregisterMe() method and the client has a callback method called Announcement(string message) that, through the CallbackContract mechanisms in WCF, the server can call. This seems to work well.
Unfortunately, in this setup, if the Server were to crash or is otherwise unavailable, the Client won't know since it is only listening for messages. Silence on the line could mean no Announcements or it could mean that the server is not available.
Since my goal is to reduce polling rather than immediacy, I don't mind adding a void Ping() method on the Server alongside RegisterMe() and UnregisterMe() that merely exists to test connectivity of to the server. Periodically testing this method would, I believe, ensure that we're still connected (and also that no Announcements have been dropped by the transport, since this is TCP)
But is the Ping() method necessary or is this connectivity test otherwise available as part of WCF by default - like serverProxy.IsStillConnected() or something. As I understand it, the channel's State would only return Faulted or Closed AFTER a failed Ping(), but not instead of it.
2) From a broader perspective, is this callback approach solid? This is not for http or ajax - the number of connected clients will be few (tens of clients, max). Are there serious problems with this approach? As this seems to be a mild risk, how can I limit a slow/malicious client from blocking the server by not processing it's callback queue fast enough? Is there a kind of timeout specific to the callback that I can set without affecting other operations?
Your approach sounds reasonable, here are some links that may or may not help (they are not quite exactly related):
Detecting Client Death in WCF Duplex Contracts
http://tomasz.janczuk.org/2009/08/performance-of-http-polling-duplex.html
Having some health check built into your application protocol makes sense.
If you are worried about malicious clients, then add authorization.
The second link I shared above has a sample pub/sub server, you might be able to use this code. A couple things to watch out for -- consider pushing notifications via async calls or on a separate thread. And set the sendTimeout on the tcp binding.
HTH
I wrote a WCF application and encountered a similar problem. My server checked clients had not 'plug pulled' by periodically sending a ping to them. The actual send method (it was asynchronous being a server) had a timeout of 30 seconds. The client simply checked it received the data every 30 seconds, while the server would catch an exception if the timeout was reached.
Authorisation was required to connect to the server (by using the built-in feature of WCF that force the connecting person to call a particular method first) so from a malicious client perspective you could easily add code to check and ban their account if they do something suspicious, while disconnecting users who do not authenticate.
As the server I wrote was asynchronous, there wasn't any way to really block it. I guess that addresses your last point, as the asynchronous send method fires off the ping (and any other sending of data) and returns immediately. In the SendEnd method it would catch the timeout exception (sometimes multiple for the client) and disconnect them, without any blocking or freezing of the server.
Hope that helps.
You could use a publisher / subscriber service similar to the one suggested by Juval:
http://msdn.microsoft.com/en-us/magazine/cc163537.aspx
This would allow you to persist the subscribers if losing the server is a typical scenario. The publish method in this example also calls each subscribers on a separate thread, so a few dead subscribers will not block others...