Testing For Developers

This section is for developers. There is a directory called com.tymeac.test. This section explains what those classes are and how to use them. See also the internal structure document.

Testing multi-threaded applications can drive anyone to drink. Modifying Tymeac, without an IDE to single step code, is a guarantee to failure. Even with a good IDE there are storage areas of interest to developers during execution that cannot be displayed by the IDE. (Before object-oriented you could get the address of the storage area you needed and go peek at what was in memory or get a core dump and spend your life with a hex calculator.)

The client directory contains classes for general purpose. Anyone can look at what stage the thread are in, how many of these and those have happened. But what we really need to know is the internal status of the environment. That is, what does a Queue Area look like, right now. How many sync/async requests are active and what are the details of each.

We also have a few quickies to modify the DBMS tables (delete, insert, retrieve.)

TyDBdelete
TyDBinsert
TyDBretrieve

We also have quickies to display and modify the Derby and Hypersonic databases both as an embedded database server and a network database server. You can easily modify the code to use any other data base management system.

DerbyDelete
DerbyFuncTable
DerbyListTable
DerbyLogTable
DerbyStatsTable
DerbyQueTable
HsqlDelete
HsqlFuncTable
HsqlListTable
HsqlLogTable
HsqlStatsTable
HsqlQueTable

 

In a nutshell,

The Tymeac management modules are all in com.tymeac.base.

Tymeac accepts a client request syncRequest() / asyncRequest()

Tymeac creates a RequestDetail object for the request and saves it in the RequestHeader detail list (ConcurrentLinkedQueue.)  Each client request returns a pointer to the newly created RequestDetail object. The purpose of these objects is to hold the information necessary to track the request and to recover from exceptions. When the current request finishes, Tymeac frees the RequestDetail.

To free the object, Tymeac sets the status of the RequestDetail to 64 and removes the RequestDetail from the RequestHeader ConcurrentLinkedQueue. This should be the last live reference to the object so garbage collection may proceed. Since remove() doesn't remove the element immediately, iterating the list returns these freed objects. Eventually, the freed objects disappear.

Prior to release 5.3, Tymeac used a home-grown method of managing the RequestDetail objects. When each RequestDetail was free, it was reused saving allocate/de-allocate overhead. The garbage collection algorithms are so good today, the home-grown method is no longer efficient.

The RequestHeader contains methods to iterate the detail list, add and remove elements.

SyncRequest()'s time-out. After a very long interval, Tymeac will free the RequestDetail.

AsyncRequest()'s stall and may be manually freed by an administrator.

Tymeac places the pointer to the RequestDetail object into a wait list (Class WaitLists) in each Queue required by the Function. The threads retrieve that pointer to process the request. Waitlists arrays for the pointers are actually ConcurrentLinkedQueue<RequestDetail>.

Tymeac then MAY inform a thread on each Queue (Class AreaHeader) to do the work. (When threads finish processing other requests they look in the wait lists for more work.)

Each Queue has one or more threads but they are not the traditional "thread pool" type. The Queue contains a Class, AreaDetail, for each thread so Tymeac can manage each thread individually. This is the big difference between Tymeac and the concurrent utility Thread Pool classes.

Think of thread pools as a pool of sharks swimming around looking for prey. You wouldn't want to venture into that pool. Tymeac's Queue Threads are well-behaved, leashed threads that fetch prey, consume it and then return to the corral all under the watchful eye of the Tymeac Monitor.

  • When no thread is working, Tymeac starts a new thread.
  • When a thread is 'waiting for work', Tymeac uses a Condition.signal() to wake up the thread.
  • For the steps Tymeac uses to inform the thread, see method AreaHeader.schedule().

Tymeac waits for all the Queues to finish for syncRequest() and passes back the Object[] to the caller or returns immediately for asyncRequest().

Additionally, for asyncRequest(), Tymeac may schedule an output agent (new asynchronous process) when the original processing completes.

Of concern to developers are the internal arrays Tymeac uses to process the requests.
    AreaHeader -- Queue data and pointer to Wait Lists
        AreaDetail -- Queue Threads (one for each thread)
    RequestHeader -- Requests array (anchor point for details)
        RequestDetail -- Request data

The main Tymeac interface is TymeacInterface. Implementing that interface is TymeacImpl. The implementation contains a method diagnose(). You can put anything in there you want. Naturally, you must also add code to the Tymeac classes you want to look at. What is in there now is code to display (System.out.println) the contents of the various arrays. These display on the Server window since they run in the Server JVM. The clients display an 'ok' message.

For example: to display all sync requests currently in the system, the client fills in the Class TyParm (String, int, int, int) by setting the first two int's to 1, 2 respectively. The client calls the Tymeac Server diagnose() method. The diagnose() calls the RequestHeader object like so:
       
        request_tbl
.dsplyActiveSyncDetails();

 diagnose() returns an OK message to the client. dsply...() prints the list of active sync requests on the console window such as:

Total ALL Slots in use =  160, SR Slots in use at first scan = 50, total requests handled = 2000
Next Detail
In=000000000000000000 Na=2 #Q=2 Now=1 Next Output=1 Backout=false Waittime=20000 Status=1

What this means for a sync request is:

  • Total slots is the total RequestDetail objects in the RequestHeader ConcurrentLinkedQueue. These are the Sync, Async and the freed objects mentioned above (status=64.)
  • Total requests handled is just that.
  • ...In use at first scan is the total busy details Tymeac found by enumerating the number busy. Since there is no locking, when Tymeac prints the busy elements (below) the number may change.
  • When the count is zero, Tymeac says so and terminates. Otherwise Tymeac prints each busy detail. Tymeac starts at the beginning of the array and prints each busy entry as it finds it. Since there is no locking, the number of printed entries may not match the above first scan number.
  • Next Detail is just a marker between details.
  •  In= is the input to the request using method: toString().
  • Na= is the sequence number of this request starting at one (1).
  • #Q= is the total number of Queues for this request.
  • Now= is the number of Queues still to process. If the total is 3 and Now= 1, then two finished and one is remaining.
  • Next output= is the next available subscript to put a return object from a Queue Thread. The return of your Processing Application Class may be an object. Tymeac saves all the objects from all the Queues in the request and returns that array to the client. Tymeac puts the return object into an array of objects using an AtomicInteger starting at zero (0). Next Output is that integer. For the above, the integer is 1. This means that element 0 was used and 1 is next.
  • Backout= true, the request timed-out or was cancelled. false otherwise.
  • Waittime= The time in milliseconds this request will wait for all Queues to finish.
  • Status= This is an integer. See RequestDetail for the values. (1 is busy) 

Remember -- Tymeac does not use locking to gather this information. The in-use-at-first-scan may be one and two details may print or no details may print or anything else. Even the information contained in each detail may have changed since it was fetched and printed.

Displaying this information for an active system may be useless. We use it when we think there are timed-out requests or when the system is quiet and we use the Overall_Display and it says there are active (a)sync requests. So, we run this diagnose() to see what is going on.

To use the supplied clients, duplicate any of the supplied client access scripts and change the class to execute from com.tymeac.demo... to com.tymeac.test.?? where ?? is as follows:

TyDisplayAreaAAAA (AAAA - DDDD and Notify) these are the supplied demonstration Queues Alter these as necessary for your own Queues.

TyDisplay??table -- Where ?? is AR for the async RequestDetail elements, SR for the sync RequestDetail elements and STALL for the stall array.

TyDisplayFUNCtable -- To display the current functions. (similar to the client display but displays all the functions in the system)

TyDisplayFUNCques -- To display the current functions with their queue names.

You can add anything you like here without impacting Tymeac.

© 1998 - 2007 Cooperative Software Systems, Inc.  All rights reserved.