Re: Remoting, Singletons and multi-threading (and now performance!)
Thanks for your reply once again.
All clients wish to share the same data. 99% of the time the access will
be read which will allow multiple clients to access the same data at the
same time. Only when I have a write do I need to lock out a particular piece
of data for the period of the write.
I've been playing around and as far as I can see, all calls to the Singleton
get called on the same thread, but I couldn't swear to this. Certainly if
I change the name of the current thread in one Singleton call then it's still
changed when the next call comes in. Which seems odd and would imply that
it's the same thread.
Ideally I want every client access to come in and then work on its own thread
and providing that is a read operation then no problem but if it's a write
then I'll apply a locking technique to make sure that only the writer has
access and lock the readers out for that brief period.
So I still don't know how to make the Singleton go multi-threaded... or does
it by default which isn't the behavour I've (crudely) tested.?? ??
There are two types of data that will exist in the Singleton; permanent data
(the data cache) which is shared between all clients and temporary data used
for the life of the call. There is no requirement for data other than that
in the cache to be maintained between calls i.e. it has the characteristics
of a SingleCall service in this respect but I cannot use the SingleCall model
because I wouldn't be able to maintain shared data!
The whole purpose of this is to store frequently-used reference data in memory
so that I don't have to keep going back to the database to get it. Yes, the
Singleton will become a bottleneck but no more than having a single DB at
the back-end; and access should be a lot quicker because (1) it's all in
memory (2) it's accessed via. fixed parameters rather than having to parse
an SQL statement (ok, so stored procedures help this anyway), and (3) it's
preformatted to how the client program wants to use it and this is only needed
to be done initially when all reference data is loaded and occasionally thereafter
when individual data parts are changed.
It's a standard write-through cache, so when a data change is made the Singleton
will update the data in memory and write to the database as an atomic operation,
but as I said this won't happen very often, the major majority of cals will
be to read some data.
I've also done some small performance tests and it seems that the first call
to the Singleton by a client incurs a 160mS hit and then <10mS for subsequent
calls (the Singleton is running on the same machine as the client).
Even if another client has already created a reference and made a call to
the Singleton (without finishing its work) before the second client accesses
it then the second client *still* gets a 160mS hit. Which doesn't seem very
good to me and certainly isn't what I think I've experienced when using DCOM.
I wondered if it was something to do with establishing the TCP/IP connection
but DCOM always used TCP/IP under Win 2K by default anyway.
More responses eagerly awaited!
"Rob Teixeira" <RobTeixeira@@msn.com> wrote:
>This is more or less what i was alluding to.
>In this case, you'd want to create seperate data slots for each thread instead
>of using field variables. Field variables are by default available to all
>threads, which is where the multi-threaded problem comes into play.
>To make seperate data slots, use the Thread method AllocateDataSlot or AllocateNamedDataSlot.
>You can then call GetData to access the values. Use this in place of variables.
>Data slots belong to a specific thread and are not shared between threads.
>The other thing that might be of interest is the ThreadStaticAttribute.
>this attribute to a field makes its value unique to each thread. It only
>works for Shared (static) fields, but since you have a Singleton, there's
>only one instance anyway, so there's nothing to stop you from making them
>all Shared fields.
>There are only two things that concern me:
>1) Are all remote clients guaranteed to receive a unique thread?
>2) Does a client get the same thread between calls?
>If not, you'll have to create your own mechanism for storing unique values,
>much like a thread-safe SharedPropertyManager.
>Honestly though, if you need to make all these fields unique, then you are
>essencially creating new instances of the object for each client anyway
>so before getting into all this, i'd consider changing your model away from
>The only other safe way of handling this scenario is to lock field variables
>so only one thread has access to them at a time, but if you expect a high
>number connections, this will be a big bottleneck for your app.
>"Gwyn Carwardine" <email@example.com> wrote:
>>Thanks chaps for your replies. I'm obviously not being clear!
>>I want my singleton class to maintain state across client calls. However
>>if a second client calls it before the first has been returned his data
>>want the singleton to process this second request in parallel. (The singleton's
>>purpose is to be an instorage cache. Huge read:write ratio)
>>What I don't understand is how I achieve this. Threads come into it somewhere
>>of course but what do I have to do to achieve this. Anything? Nothing?