Correlating IComMethodEvents
Asked Answered
A

2

10

When implementing IComMethodEvents you get three events.

  1. OnMethodCall
  2. OnMethodException
  3. OnMethodReturn

The goal of what I am trying to do is to log call times per method in COM+ components.

The time of the event can be retrieved by using lTime and lMicroTime in the COMSVCSEVENTINFO structure so by logging that time in both OnMethodCall and in OnMethodReturn I should be able to calculate the call time but how can I be sure that the two events are related.

By testing it looks as I should be able to use the just-in-time (JIT) activated object oid.

Any problems in doing it like that or are there other ways?

One problem that might be is that I see the oid is frequently being reused so if the events for some reason is fired out of order it might be a bit more difficult to implement the correlation.

Update 1:

Further testing shows that oid is not enough in a multi user scenario. The same object is used at the same time so correlation has to be done using at least oid and original caller. A follow up question would be: How to get the original caller from a COM+ event subscriber?

Update 2:

Just found IComMethod2Events. Difference is that the events has an identifier of the thread executing the call. Looks promising in tests and I can't imagine a scenario where the correlation could fail. The threading model for the COM+ components are Any Apartment.

Update 3

In this article Creating COM+ PerfMon Counters to Monitor COM+ Data oid is used. I don't think that is enough in a multithreaded apartment.

Note: I will eventually implement this in Delphi so I added the Delphi tag. I also added the C# tag because chances are that the language used to implement the interface is not important at all. Update: Tentatively adding the c++ tag just to draw the attention of someone who has actually used this stuff before.

Audryaudrye answered 14/3, 2013 at 6:50 Comment(3)
A tool to monitor COM+ transactions: AppMetrics. Perhaps useful and you may figure out how they do the monitoring.Pickard
This page may also be helpful, MSDN COM+ Tracking.Pickard
@LURD thanks for the links. Read a bit from the MSDN link and COM+ Instrumentation will eventually lead you to the events in the Q. COM+ Tracking will let you get the data COM+ gathers for you but only down to component level (I think).Audryaudrye
B
3

...if the events for some reason are fired out of order...

They never do. The COM+ system event publisher fires these events using COM+ Events service. Invocation of an event is synchronous from event publisher's point of view. When a publisher fires an event, it doesn't proceed with the next one until all the subscribers complete processing of fired event. Quite naturally, OnMethodReturn/OnMethodException events are not published before matching OnMethodCall ones. I recall reading KBs concerning race conditions/broken subscriptions in COM+ events. All of those bugs, to my knowledge, have been addressed in various Service Packs for Windows 2000. Though, admittedly, I do not try to stay up-to-date in this area.

When implementing IComMethod2Events you subscribe to the very same transient subscription as for IComMethodEvents. So order of fired events is the same too.

...so correlation has to be done using at least oid and original caller...

At this point I'm really not sure whether you do interpret results of your tests correctly. How do you test, exactly?

oid should already encapsulate all the information required, even in "multiple clients" scenario with JIT and pooling. Last time I implemented such event listener (it has been a while), relying on oid worked out fine. Though, majority of components in my environment was written in VB6 (hence, lived in STA). Yet, even with STA you can have several calls at various stages of execution by a single thread. As there is an upper bound for number of threads in COM+ STA thread pool you can have the following situation: call A starts on particular thread, call B starts on the same thread, call B returns, call A returns. I do not recall any trouble tracking the calls by oid without "some additional info about the caller".

Implementation idea you consider is, by large, canonical. COM+ spy sample that comes with Platform SDKs uses oid argument to trace individual calls. You can find the application's sources in <Path to SDK samples>\Samples\com\administration\spy. The sample has been using this implementation for quite a while (since Windows 2003 at least). And today it is aeons after MTA and even COM+ introduction. Should there be flaws the sample would be updated at this point. Hopefully.

Beal answered 8/4, 2013 at 0:14 Comment(1)
Thanks for providing an answer. You were right in questioning my tests. I can not reproduce what I saw earlier so I probably did a stupid mistake before. I thought I saw a second call event for an oid before the return event on the first call.Audryaudrye
K
1

The MSDN link "Creating COM+ PerfMon Counters to Monitor COM+ Data" seems to do pretty much what you are aiming for (although in managed C++ I think).

The relevant part is this, I guess:

void IComMethodEvents.OnMethodCall(ref COMSVCSEVENTINFO ei, ulong
    lObjID, ref Guid gClsID, ref Guid gIID, uint nIndex)
{
    //Make sure that monitoring is enabled and that our performance
    //counter has been initialized.
    if (Monitor && pcMethodDuration != null)
    {
    try
    {                    
        //We are going to store the initial value in a Sorted List 
        //collection. To do this we are going to need a key that
        //represents this call.
        string strKey = lObjID.ToString() + gClsID.ToString() + 
            gIID.ToString() + nIndex.ToString();

This might be the solution to your pondering about oid (lObjID in their example). Don't know if this covers your multi-user scenario, you'll have to give it a try. The page has quite a bit of details on the subject so hopefully you'll be able to figure it out. Good luck.

Khoury answered 7/4, 2013 at 16:25 Comment(3)
Yes, that was the article I referred to in update 3 of the question. I believe it will not work doing it like that. What would be really nice is some documentation about why the IComMethod2Events interface was added. I suspect it is there to solve the correlation issues in a MTA but I have found nothing about it.Audryaudrye
Ah, sorry - you're right. :) My bad. I have no experience with that interface so I cannot help you, but I suggest making a simple multi-threaded app and test the approach ("Creating COM+ PerfMon Counters...") mentioned, to see if it works as expected or not. How about that?Khoury
Yes, I did just that (again) with different outcome as you can see in a comment to the other answer. I must have made a silly mistake the first time I tested this. Thank you for the time you have spent answering my question.Audryaudrye

© 2022 - 2024 — McMap. All rights reserved.