F$GETQUI Context

From VSI OpenVMS Wiki
Revision as of 23:03, 18 June 2020 by Madsweeney (talk | contribs)
Jump to: navigation, search

A queue manager will receive requests simultaneously from many processes and from many different threads within a process. The queue manager must maintain context for all of the requesting threads on the cluster. A data structure called the GETQUI_CONTEXT is passed back and forth between a queue manager and a client to manage communication. The context maintains a "pointer" to tell a queue manager where to retrieve information for the next F$GETQUI call. Context is an opaque structure and is not user visible.

Processes have one built-in queue context called the Default Context, context number 0 (zero). Whenever the context is omitted from a F$GETQUI call, context 0 is used. DCL commands that retrieve queue system information like SHOW QUEUE and SHOW ENTRY contain many sys$getqui() system services calls using the default context. Remembering queue commands use the default context is important for DCL programmers because it can cause unexpected results from F$GETQUI calls using the default context.

An example may explain the concept of the context best.

Suppose your system or cluster has 3 queues, AQ, GQ and ZQ. The SHOW QUEUE command below makes 4 sys$getqui() calls to retrieve the queue information to output on your device. The figure below illustrates the contents of the GETQUI_CONTEXT data structure during the four sys$getqui() calls. The default context is used the four sys$getqui() calls. The text to the left of the bars is the DCL input and output. To the right of the bar is the value of the GETQUI_CONTEXT value followed by a short description of the processing of the sys$getqui() call.


SYSTEM IA10> show queue/summ %Q   |GETQUI_CONTEXT    Description
                                  |     <null>       client process sends null in getqui context
Batch queue AQ, idle, on IA10::   |-----------------                    
                                  |      AQ          queue manager looks up the first queue in it's database
    Job summary:  queue is empty  |                  queue manager returns AQ to client in getqui_context
                                  |-----------------                 
                                  |                  client process sends AQ to the queue manager in getqui_context
Batch queue GQ, idle, on IA10::   |                  queue manager uses client passed AQ to lookup the next queue in the database 
                                  |      GQ          queue manager finds GQ, updates the getqui_context with GQ  
    Job summary:  queue is empty  |                  queue manager returns GQ to client in getqui_context
                                  |-----------------
Batch queue ZQ, idle, on IA10::   |                  client process sends GQ to the queue manager in getqui_context
                                  |      ZQ          queue manager uses client passed GQ to lookup the next queue in the database         
    Job summary:  queue is empty  |                  queue manager finds ZQ, updates the context with ZQ
                                  |                  queue manager returns ZQ to client in getqui_context
                                  |-----------------
                                  |                  client process sends ZQ to the queue manager in getqui_context
                                  |                  queue manager looks up the next queue in the database
                                  |                  No queue found after ZQ
                                  |                  Queue manager returns JBC-Q-NOMOREQUE

When querying the queue system for information, the sys$getqui call message to the queue manager


  • DISPLAY_CHARACTERISTIC
  • DISPLAY_ENTRY
  • DISPLAY_FILE
  • DISPLAY_FORM
  • DISPLAY_JOB
  • DISPLAY_MANAGER
  • DISPLAY_QUEUE

Establishing a Context

To establish a queue context, make a wildcard call to F$GETQUI using a DISPLAY_QUEUE function, for example:

$  QNAME = F$GETQUI("DISPLAY_QUEUE","QUEUE_NAME","*") 
 

Calls to F$GETQUI between this one and the next similar call will use the context of this queue. For example:


$ SHOW QUEUE

Batch queue QUEUE$ONE, idle, on SMAN43::

Generic printer queue SYS$PRINT

  Entry  Jobname         Username     Blocks  Status
  -----  -------         --------     ------  ------
     70  TEST1            JDOE         1     Pending
         (32 intervening jobs containing 65 blocks)
     71  TEST2            JDOE         3     Pending

$  QNAME = F$GETQUI("DISPLAY_QUEUE","QUEUE_NAME","*") 
$ SHOW SYM QNAME
  QNAME == "QUEUE$ONE"
$  NAME_ONE = F$GETQUI("DISPLAY_JOB","JOB_NAME",,"ALL_JOBS")
$ SHOW SYM NAME_ONE
  QNAME == ""
$  NAME_TWO = F$GETQUI("DISPLAY_JOB","JOB_NAME",,"ALL_JOBS")
$ SHOW SYM NAME_TWO
  QNAME == ""
$  QNAME = F$GETQUI("DISPLAY_QUEUE","QUEUE_NAME","*")
$ SHOW SYM QNAME
  QNAME == "SYS$PRINT"
$  NAME_THREE = F$GETQUI("DISPLAY_JOB","JOB_NAME",,"ALL_JOBS")
$ SHOW SYM NAME_THREE
  QNAME == "TEST1"
$  NAME_FOUR = F$GETQUI("DISPLAY_JOB","JOB_NAME",,"ALL_JOBS")
$ SHOW SYM NAME_FOUR
  QNAME == "TEST2"
 

SHOW QUEUE reveals that we have two queues, QUEUE$ONE and SYS$PRINT. QUEUE_ONE has no jobs in it and QUEUE$PRINT has two jobs pending. The first call to F$GETQUI establishes queue context of the first queue - QUEUE$ONE. All subsequent calls to F$GETQUI until the context is changed obtain information within that context, i.e. on that queue. There are two calls to DISPLAY_JOB, both return an empty string, because there are no jobs in that queue and therefore their names are empty strings. The second call to F$GETQUI advances queue context, so all subsequent calls operate within the context of SYS$PRINT rather that QUEUE$ONE. And since SYS$PRINT has jobs, we start seeing actual names for these jobs. Note that DISPLAY_JOB establishes job context; if we wanted to display additional information for job TEST1 - say, its entry number - that call would have to include the "FREEZE_CONTEXT" flag at the end, otherwise the job context would advance and you would get the entry number of TEST2 (71) rather than TEST1 (70):

$ QNAME = F$GETQUI("DISPLAY_QUEUE","QUEUE_NAME","*") $ SHOW SYM QNAME QNAME == "SYS$PRINT" $ NAME_THREE = F$GETQUI("DISPLAY_JOB","JOB_NAME",,"ALL_JOBS") $ SHOW SYM NAME_THREE QNAME == "TEST1" $ ENTRY = F$GETQUI("DISPLAY_JOB","ENTRY_NUMBER",,"ALL_JOBS") $ SHOW SYM ENTRY B = 71 Hex = 00000046 Octal = 00000000106

Preserving the Context

To preserve context, use the "FREEZE_CONTEXT" flag. It is available for all functions that establish context. Here is how it can be used to preserve job context:

$ SHOW QUEUE Batch queue QUEUE$ONE, idle, on SMAN43:: Generic printer queue SYS$PRINT Entry Jobname Username Blocks Status ----- ------- -------- ------ ------ 70 TEST1 JDOE 1 Pending (32 intervening jobs containing 65 blocks) 71 TEST2 JDOE 3 Pending $ QNAME = F$GETQUI("DISPLAY_QUEUE","QUEUE_NAME","*") $ SHOW SYM QNAME QNAME == "SYS$PRINT" $ NAME_THREE = F$GETQUI("DISPLAY_JOB","JOB_NAME",,"ALL_JOBS") $ SHOW SYM NAME_THREE QNAME == "TEST1" $ ENTRY = F$GETQUI("DISPLAY_JOB","ENTRY_NUMBER",,"FREEZE_CONTEXT") $ SHOW SYM ENTRY B = 70 Hex = 00000046 Octal = 00000000106

In the example above, NAME_THREE = F$GETQUI("DISPLAY_JOB","JOB_NAME",,"ALL_JOBS") is used to establish job context of job TEST1 with entry number 70. The subsequent call uses the "FREEZE_CONTEXT" flag, so the context remains that of TEST1 and its entry number (70) is displayed. Had that flag not been used, the job context would advance and the entry number of the next job (TEST2; 72) would be displayed - that is illustrated at the end of the section above.

Cancelling a Context

A context can be cancelled with a call to F$GETQUI CANCEL_OPERATION function:

a = f$getqui("CANCEL_OPERATION")
 

The symbol does not matter. It is recommeded to do this every time before establishing a new context to make sure that no contexts that may have been established by the previous command procedures interfere with it.