Nigel,
Sorry for the late reply! It seems that only two of us on this newsgroup are
using (or testing) queued components! I can see only my unreplied post, and
the two of yours on the subject!
Ok, back to work. I ran some tests with QC + Object Pooling features of
COM+.
My test environment matches yours.
That's what I got:
* All calls made became committed transactions, no matter how many objects
were on the pool; I tried several settings on the MaxPoolSize parameter,
starting with 1 and going up to 32; I always stopped and restarted the COM+
app after changing this settings.
* The only aborts I got (no doubt about that) were due to the following:
1. Every time MaxPoolSize is lower than (MaxListenerThreads * Number of
CPUs), there will be ((MaxListenerThreads * Number of CPUs) - MaxPoolSize)
listener threads waiting for a player object to become available, in case
there are enough messages waiting in the queue.
2. Under the above circustances, every time I stopped the COM+ Application
(to change the MaxPoolSize setting), I got ((MaxListenerThreads * Number of
CPUs) - MaxPoolSize) aborted transactions.
3. MaxListenerThreads (property of
System.EnterpriseServices.ApplicationQueuingAttribute) (which is called
Maximum Concurrent Players on the Components Services MMC), has the default
value of 16 per CPUs when not set (or when set to 0="default" on MMC).
So, I could not reproduce the situation you described. In my tests, the
called method was actually of a "do not" nature
(System.Threading.Thread.Sleep(random millisseconds - range 50 - 400 ms)).
Some things I would like to know about your scenario, are:
1. Do you get a reference to the recorder interface, call the method and
release; repeat 2000 times; or do you get a reference to the recorder
interface, call the method 2000 times and release?
2. How long it takes to to actually "execute" that call (when the player
gets invoked by the queue listener thread)?
3. Did you override the CanBePooled method of ServicedComponent class,
forcing it to return true (it will allow the "player" component to be sent
back to the pool, instead of being destroyed by the COM+ runtime)?
4. Did you try to set MaxPoolSize >= (MaxListenerThreads (default is 16 per
CPU) * Number of CPUs) adjusting either MaxPoolSize or MaxListenerThreads?
The motivation here is to allow the pool to be large enough to always
fulfill the needs of the existing Queue Listener Threads.
I'm asking Q2 because I think we can have problems if no "player" becomes
available on the pool before the "Creation Timeout" expires. That will not
explain why you do not get aborts with the pool set to 1 (I assuming that
your "Pool Size" means MaxPoolSize; is that right?) and you do with a larger
pool, but I think it's something to be aware of, anyway.
I have projects running fine on production with QC. Those projects are using
QC + Distributed Transacions. I'm going to launch a new a system using QC +
Distibuted Transactions + COM+ Partitions (that was the subject on my
previous post). I had never tried QC + Object Pooling togheter before.
Good luck on your tests,
Marcelo
> Environment:
> COM+ 1.5, Server 2003, MSMQ 3.0, workgroup (Single CPU machine)
>
> I am testinig QC,
> When I make 2000 calls on the QC Interface, and the Component has a configured Pool Size of 2 (or more) I receive a high number of aborted
transactions (951 in this case). but 2000 are committed (i.e. the number of
calls.
> However, when the Pool Size is 1, 2000 Transactions are committed and 0 aborts.
>
[quoted text clipped - 3 lines]
>
> Thanks all