By: Steven Shaughnessy
Abstract: This article describes the threading model employed by the 2009 edition of DataSnap.
The 2009 DataSnap server has a simple threading model. DataSnap 2009 no longer requires the usage of Microsoft’s COM. However if COM based components will still be used in a DataSnap 2009 server, a COM multi-threaded concurrency model is probably the easiest to use in the context of a DataSnap 2009 server.
The transport component manages the creation and lifetime of threads. The transport implementation can choose to reuse threads by managing a thread pool. As of this writing TDSTCPServerTransport component is the default transport for DataSnap 2009. However the client and server side transport implementation can be easily replaced. TDSTCPServerTransport currently uses the Indy 10 library to provide a simple blocking socket server with a configurable thread pool.
For every client side connection instance there is a corresponding server side connection instance. All messages are executed in the context of the server side connection. Messages include requests for operations like the execution of server methods, sql queries and provider data synchronization interactions. All DataSnap 2009 clients should ensure that only one client thread uses a client side connection at a time. The corresponding server connection instance depends on this discipline.
At any point in time there is only one thread using a server connection instance to service a message. With a blocking transport implementation, the thread never changes from one message request to the next. When support for non-blocking transports is provided, the thread using the server connection can change from one message request to the next.
In general there is very little thread synchronization automatically employed by the DataSnap 2009 server. Monitors, critical sections, semaphores or mutexes can be used to provide thread safe access when needed. The new TMonitor class in Delphi is lightweight, fast and easy to use. The choice the TDSServerClass LifeCycle property plays an important role in deciding whether an application needs to provide thread safe access to server class instances.
With this lifecycle there is a single instance of the server class shared across all server connection instances. With this lifecycle it is quite likely that thread safe access will need to be employed if server class instance data is being modified.
With this lifecycle there is a separate instance of each server class for each server connection. This provides thread safe access to the server class instance.
With this lifecycle there is a separate instance of each server class for each invocation of a server class method. This provides thread safe access to the server class instance.
COM has its own instancing and threading support. To use COM objects CoInitializeEx must be called first. Calling CoInitilizeEx with a COINIT value of COINIT_MULTITHREADED causes COM components to use a threading model that is most consistent with the threading model employed by DataSnap 2009. However not all COM components can be used with the COINIT_MULTITHREADED threading model.
If a COM threading model of COINIT_APARTMENTTHREADED is required, it may be best to use the session lifecycle setting for your TDSServerClass components since this lifecycle only allows one connection to have access to a server class instance. However if a non-blocking transport is created in the future such a transport would not guarantee a 1-1 relationship of thread and connection.
The DataSnap 2009 server default transport implementation manages a pool of threads used by the DataSnap 2009 to process all messages. The TDSServer OnConnect and OnDisconnect events handlers can be used to call CoInintializeEx and CoUninitialize for each thread when ever a thread is being associated with a connection.
Download Delphi 10 now!
Webinars on demand!
More social media choices:
Delphi on Google+
@RADTools on Twitter
Server Response from: ETNASC03