Every attempt has been made to ensure that all function calls are made aynchronously and that control is returned to the Telecom engine Scheduler as quickly as possible. However, even though all connection opens and recordset queries are specified to be carried out asynchronously, the various calls still seem to block briefly. The adoConnOpen(), adoRSetQuery() and adoRSetCmd() functions can block for something in the order of 100 - 200ms on a local area network before returning control back to the calling task. This may seem a fairly short time, but considering that the Telecom Engine task scheduler will swap tasks at a rate of many tens of thousands of times per second, then this delay can cause a significant performance drop if many tasks are attempting connections or queries at the same time.
A solution is to establish all connections at start-up and try to limit the number of queries being made by the application (do not poll continuously on a database without a significant delay between polls for example). Alternatively the use of stored procedures should increase the performance of queries, and it might be useful to carry out performance tests on a datasource to understand where performance problems may arise.
The adoTrace() function allows for tracing of the entry and exit points of all ado functions and this also provides information about how long the function took to complete (in ms). Note that the time shown by the trace will be the time taken to execute the actual ado command and not the time it took for the complete asyncronous action to complete.
For example the following trace is taken from a call to adoConnOpen():
20090218 135453.162 Task 0000 adoConnOpen() [Entry]
20090218 135453.162 About to Connect open Provider=MSDASQL.1;Password=admin;User ID=postgres;Data Source=MyDSN
20090218 135453.162 Marking connection 0 STATE_PENDING
20090218 135453.363 Task 0000 adoConnOpen() [Exit]: Returns 0: Function took 203ms
Even though the adoConnOpen() function is still blocking waiting for the ConnectionComplete event to be triggered it can be seen that the underlying _ConnectionPtr->Open() function took 203ms to complete (even though adAsyncConnect is automatically specified in the options for the Open() call). Later in the same trace log one can see the ConnectionComplete event triggered which wakes up the calling task some 352ms later:
20090218 135453.715 EVENT (CONNECTION) CONNECTCOMPLETE: TaskID=0 handle=0 status=1
20090218 135453.715 Marking connection 0 STATE_OPEN
Similarly in the trace below for an adoRSetQuery() call which attempts to select all the records from the billing table (>9000), the initial call to adoRSetQuery() takes 74ms, which is actually quite quick and would not present a great deal of problems performance-wise as long as there wasn't a continous loop calling these queries very frequently:
20090218 135453.723 Task 0000 adoRSetQuery() [Entry]
20090218 135453.724 About to RSet query select * from billing
20090218 135453.724 Marking recordset 0 PENDING
20090218 135453.795 Task 0000 adoRSetQuery() [Exit]: Returns 0: Function took 74ms
20090218 135516.059 EVENT (CONNECTION) EXECUTECOMPLETE: TaskID=0 handle=0 status=1
20090218 135536.059 EVENT (RECORDSET) FETCHCOMPLETE: TaskID=0 handle=0 status=1
20090218 135536.060 Marking recordset 0 STATE_OPEN
The actual query took quite a long time since it selected all records from the billing table which contained about 9000 records.
Notice that the adoRSetQuery() triggers two events. First the ExecuteComplete event is triggered first after about 23 seconds (which is ignored because this is an adoRSetQuery() call), then the FetchComplete is triggered 20 seconds later which is the one we are actually interested in and which wakes up the calling task.
An understanding of the trace output will be helpful in identifying potential performance issues and designing appropriate mechanisms to ensure that they don't effect the running of the system. Be aware that different providers function in different and unpredictable ways and it might be necessary to experiment with the ADO library function calls to understand the behavior fully,,