How a Thread Becomes Disabled.

This section details the reasons a Tymeac Thread becomes logically disabled.

The status of Queue Threads (Threads for this discussion) is relevant to scheduling.

Threads process a request and then look in the Wait Lists for the next request.

When the status of any Thread is 'busy', it is reasonable to assume that since a thread is actively processing, this Thread or another Thread will process any request put into a Wait List. It is also reasonable to assume that Threads with a status of 'notified' or 'reactivated' will become active shortly and process the Wait Lists.

When a Thread remains in an active or about to be active state for an unreasonable amount of time then something may be wrong. In such a case, marking the thread 'cancelled' and then 'disabled' after even more elapsed time is a way of eliminating the Thread from consideration during scheduling.

For a non performing Queue, rather than filling up all the Wait Lists with pending requests and returning a "no Wait List available" message to the new request, Tymeac rejects the request immediately with a "no thread available" message. The "no Wait List available" message could mean, try again later. The "no thread available" message means something is wrong.  See also scheduling failures.

The Monitor Thread notifies system administrators when all Threads are 'disabled'.

An entry becomes 'disabled' by:

1. An unhandled or re-thrown exception in a Processing Application Class. 
    Threads handle exceptions by marking the Thread 'disabled'.

2. When a user manually disables a thread in the Queue Thread display/alter.

3. When the Thread detects Immediate Shut Down.

4. The Monitor Thread changes the status from Cancelled to Disabled.

Tymeac keeps track of the time of seven events:

Timing depends on an interval of time. For Tymeac the base interval (bi) is: 

  • the Monitor interval set at start up in either the Configuration File or User Variables, or,
  • one minute if the Monitor interval is less than one minute.

1.  The time the Scheduler activates/reactivates a Queue Thread.

The maximum time allowable is 2(bi)
  (two times the base interval.)

2.  The time a Thread enters a 'Thread Processing' status (executing Tymeac code.)

The maximum time allowable is 2(bi)
 
(two times the base interval.)

3.  The time the Thread invokes the Processing Application Class.

This value is determined by the individual Queue, timeout value.

When the value is zero then the system default is used. That default is 4(bi)
 
(four times the base interval.)

When that value is greater than zero, then the Queue's timeout value is used.

4.  The time the Thread calls the Scheduler (for the Output Agent Queue).

The maximum time allowable is 1(bi)
 
(the base interval.)

5.  The time the Scheduler 'notifies' a waiting Queue Thread.

The maximum time allowable is 2(bi)
  (
two times the base interval.)

For 1-5 [ Is all this necessary? ]
When the Thread exceeds the time, the Monitor sets the entry 'cancelled'. The next time the Monitor runs, it sets all 'cancelled' entries 'disabled'. If a Thread resumes processing, the Thread resets the entry, irrespective of any prior setting. Each time the Thread changes status it resets the time. Therefore, this is not a cumulative total nor overall elapsed time.

As stated above, disabled Threads cannot participate in scheduling. However, users may enable those disabled Threads with the Queue Threads GUI/non-GUI. Now it gets interesting.

"Enabling all threads" nulls the instance reference to the actual Thread in the Thread-Management Class (AreaThreadMgmt) and sets the status of the Thread in the same class to "available for a new thread". If the old Thread awakens, it both checks to see if it's instance reference is null or if another thread has taken its place and dies gracefully. For a more detailed discussion of expunged threads, see the AreaThreadMgmt Class and the footnote.

divider.gif (931 bytes)

These next two timed events do not involve setting the status to 'disabled'. We mention them here since they are part of the seven timed events.

6.  The time the Thread begins 'waiting for work'.

The maximum time allowable is the Wait Time interval for the Thread as set in Queue Maintenance (TyQueMaint).

For 6, each Thread sets its own entry 'inactive', not the Monitor. A Queue Threshold exception must take place to reactivate this thread. For a discussion of this event, see the section on Tuning.

7.  The time the Thread enters a status of 'inactive' (6, above) and the Queue is participating in the Idle Thread Life parameter.

For 7, The maximum time allowable is the Idle Thread Life interval for the Thread as set in Queue Maintenance (TyQueMaint). When the Thread exceeds the time, the Monitor destroys the Thread. Tymeac must get a new instance of the Thread and start() it when necessary.

The interval of the timed events (1-5) is as above. Using variables for System (and Queue) would establish an exclusive environment for a particular need. When the requirements change, the variables would need changing. When the platform changes, the variables would need changing. Each application on each platform would need re-engineering each time the need changes either internally by function or externally by porting.

Tymeac event timing functions identically on all platforms. Adjusting the Monitor Thread interval sets the interval across all Tymeac timed events. Porting to any machine preserves the same application demeanor (synergy) it acts the same only faster (or slower).

See also:
     Tuning, (Wait Lists, fixed number of entries within each Queue).
     Stall Array for timing of Asynchronous Requests.
     Monitor for timing of Synchronous Requests.


Is all this timing necessary?

In order to know if all this timing is necessary we must first answer the question, "Can a thread stall or die during processing?"

The answer is yes. Hardware, operating systems, the implementation of the JVM, Tymeac code and user code can all fail at anytime. Tymeac is a professional product; professionals plan for anomalies. Now, on to the timing question.

It should be obvious that when Tymeac invokes your Processing Application Class, the execution may block or take an excessive amount of time. It may even stall completely. Therefore, timing this event is a no-brainer. That takes care of number 3.

Numbers 5 and sometimes 1 have to do with Thread state changes. That is, going from a waiting or timed waiting state to a running state. (See java.lang.Thread state codes.) It is unlikely that there would be a significant delay in the thread getting CPU time after this state change, but it could happen.

Numbers 4 and sometimes 1 have to do with creating a new thread either for the Normal or Output Agent Queue. Since creating a new thread usually involves communicating with the underlying operating system, there could be a delay. It is unlikely that there would be a significant delay, but it could happen.

Number 2 is Tymeac code. As much as we like to think it is unlikely that there could be a bug, it could happen.

Finally there is just plain something going wrong somewhere. Like the "spurious wakeup" that may happen to a waiting thread, a running thread may also die or stall or another thread may damage the current thread's control structure at the operating system level. It could happen.

The consistent phrase here is "it could happen." What we really mean is it could happen again. Having done multi-tasking/threading for many decades we've run into these problems before and we expect to see them again.

Therefore, all this timing is necessary. But what about all the overhead?

There isn't much overhead associated with this timing.

  • Each time a Queue Thread changes status it checks whether it  has been expunged. If not, it sets the current time (System.currentTimeMillis()) into the field associated with this current status and nulls the time fields associated with other status codes. This is very little work and no object creation.
  • For a heavily used system the status changes are from Tymeac code to the Application code and back to Tymeac code. This is: fetching a request from the wait list, the application process, saving the application's object and fetching the next request. Exactly where timing is most necessary (the no-brainer above.)
  • When the Tymeac Monitor runs (probably about once a minute) it checks only one timing event: the current status of the Queue Thread. This is very little work and also no object creation.

For all the benefits of timing, the overhead is piddle.

 

 

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