Previous | Contents | Index |
There are several sources of information or methods you can use when debugging queued tasks:
ACMS lets you back up task queue files without having to stop the QTI or programs that call the ACMS$QUEUE_TASK and ACMS$DEQUEUE_TASK services. To enable a program that calls a queuing service to continue processing while you back up a task queue file, have the program check for the return status of ACMS$_QUEENQSUS, ACMS$_QUEDEQSUS, or both. The ACMS$QUEUE_TASK service returns the ACMS$_QUEENQSUS status if the enqueue operations for that task queue file are suspended. The ACMS$DEQUEUE_TASK service returns the status ACMS$_QUEDEQSUS if the dequeue operations for that task queue file are suspended.
If a queuing service returns one of these statuses, the program can set a timer and then retry the call. For example, if the ACMS$QUEUE_TASK service returns the ACMS$_QUEENQSUS status, the program could wait for 10 seconds and then retry the call. The program would continue to retry the call every 10 seconds until the ACMS$QUEUE_TASK service completed successfully.
See Compaq ACMS for OpenVMS Managing Applications for information on how to back up a task queue file.
9.10 Queuing Example
This section shows an example of a car rental reservation application that uses the ACMS queuing facility. The purpose of the application is to process the customer's account when the customer returns the rental car. Because there might be peak periods when many customers return their cars at the same time, the application accepts the necessary reservation information from a customer, then queues that information to be processed at a later, less busy time. The example consists of:
Figure 9-2 shows how these items work together.
Figure 9-2 A Queuing Example
The following is the flow of events leading up to and including the example:
Example 9-5 shows the main part and the process_this_transaction subroutine of the C agent that uses the $START_TRANSW system service to start a distributed transaction, and calls the VR_FAST_CHECKIN_TASK. See Compaq ACMS for OpenVMS Systems Interface Programming for a detailed explanation of the complete agent code.
Example 9-5 C Agent that Starts a Distributed Transaction |
---|
/**************************************************************/ /* */ /* Version: 01 */ /* Edit dates: 06-MAR-90 */ /* Authors: DIGITAL */ /* */ /**************************************************************/ /**************************************************************/ /* F U N C T I O N A L D E S C R I P T I O N */ /* */ /* */ /* VR_AGENT is an ACMS agent program that acts like an ATM */ /* where you type in your reservation number and odometer */ /* reading, drop the keys in a slot, and walk away. The */ /* system bills you later for the amount you owe. The */ /* agent uses QIOs to get the data, starts a distributed */ /* transaction, then calls a task to do the work. The task */ /* consists of a nonparticipating step that validates the */ /* reservation number, a step that queues a task to do the */ /* actual checkin work, and a step that writes a history */ /* record. If the task succeeds, the agent commits the */ /* transaction. If the task fails, the agent aborts the */ /* the transaction and notifies the user of the problem. */ /* The agent is also responsible for handling errors, such */ /* as transaction timeouts. */ /* */ /**************************************************************/ /**************************************************************/ /* */ /* C O P Y R I G H T */ /* */ /* */ /* COPYRIGHT (c) 1991 BY */ /* DIGITAL EQUIPMENT CORPORATION, MAYNARD */ /* MASSACHUSETTS. ALL RIGHTS RESERVED. */ /* */ /* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND */ /* MAY BE USED AND COPIED ONLY IN ACCORDANCE WITH */ /* THE TERMS OF SUCH LICENSE AND WITH THE */ /* INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS */ /* SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT */ /* BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY */ /* OTHER PERSON. NO TITLE TO AND OWNERSHIP OF */ /* THE SOFTWARE IS HEREBY TRANSFERRED. */ /* */ /* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO */ /* CHANGE WITHOUT NOTICE AND SHOULD NOT BE */ /* CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT */ /* CORPORATION. DIGITAL EQUIPMENT CORPORATION */ /* ASSUMES NO RESPONSIBILITY FOR ANY ERRORS THAT */ /* MAY APPEAR IN THIS SOFTWARE. */ /* */ /* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE */ /* OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT */ /* THAT IS NOT SUPPLIED BY DIGITAL. */ /* */ /**************************************************************/ /* . */ /* . */ /* . */ /* . */ main () /**********************************************************************/ /* */ /* Get Procedure information to see if the application is running. */ /* */ /* While the application is up and running prompt user for */ /* reservation ID and odometer reading. */ /* */ /* If the user enters the data, process the fast checkin transaction.*/ /* */ /* If the user aborts, notify the user that the transaction was not */ /* processed. */ /* */ /**********************************************************************/ { for (;;) { status = initialization (); check_status(status); status = ACMS$GET_PROCEDURE_INFO(&submitter_id, &task_name_desc, &appl_name_desc, &task_info_list); while (status & STS$M_SUCCESS) { status = get_data (); if (status & STS$M_SUCCESS) status = process_this_transaction(); else if (status == RMS$_EOF) status = report_user_abort(); check_status(status); status = ACMS$GET_PROCEDURE_INFO(&submitter_id, &task_name_desc, &appl_name_desc, &task_info_list); } if (status == ACMS$_NOSUCH_PKG) status = application_not_running(); check_status(status); status = termination (); check_status(status); } } */ . */ */ . */ */ . */ */ . */ process_this_transaction() /********************************************************************/ /* */ /* Start Transaction. Call the task. Commit if successful. */ /* Abort if failure. Retry if timed out. Notify user whether */ /* transaction succeeded or failed. */ /* */ /********************************************************************/ { short retry, trans_completed; retry = 0; trans_completed = FALSE; while ((trans_completed == FALSE) && (retry < MAX_RETRY)) { status = SYS$START_TRANSW (0,0,&iosb,0,0,tid); if (status & STS$M_SUCCESS) status = iosb.status; check_status(status); status = call_return_task(); if (status & STS$M_SUCCESS) { status = SYS$END_TRANSW (0,0,&iosb,0,0,tid); if (status & STS$M_SUCCESS) status = iosb.status; check_status(status); trans_completed = TRUE; } else { if ((status == ACMS$_TRANSTIMEDOUT) || (status == ACMS$_SRVDEAD) || (status == RDB$_DEADLOCK) || (status == RDMS$_DEADLOCK) || (status == RDB$_LOCK_CONFLICT) || (status == RDMS$_LCKCNFLCT) || (status == RDMS$_TIMEOUT)) ++retry; else retry = MAX_RETRY; status = SYS$ABORT_TRANSW (0,0,&iosb,0,0,tid); if (status & STS$M_SUCCESS) status = iosb.status; check_status(status); } } if (trans_completed == FALSE) status = notify_failure(); else status = notify_success(); return status; } |
If the distributed transaction fails because of an error that can be handled, such as server deadlock or transaction timeout, the agent retries the distributed transaction up to five times. Example 9-6 shows the task definition called by the C agent.
Example 9-6 VR_FAST_CHECKIN_TASK Definition |
---|
REPLACE TASK AVERTZ_CDD_TASK:VR_FAST_CHECKIN_TASK USE WORKSPACES VR_FAST_CHECKIN_WKSP, VR_RESERVATIONS_WKSP, VR_RENTAL_CLASSES_WKSP, VR_VEHICLES_WKSP, VR_TRANS_WKSP, VR_VEHICLE_RENTAL_HISTORY_WKSP, VR_HIST_WKSP; TASK ARGUMENTS ARE VR_FAST_CHECKIN_WKSP WITH ACCESS READ; ! TASK MUST BE COMPOSABLE TO BE CALLED AS PART OF A DISTRIBUTED ! TRANSACTION BLOCK WORK WITH DISTRIBUTED TRANSACTION NO I/O ! ! Retrieve the reservation record, using the reservation number/ID ! entered by the customer and passed by the vr_agent agent. ! PROCESSING WITH NONPARTICIPATING SERVER CALL PROCEDURE VR_FIND_RES_PROC IN VR_READ_SERVER USING VR_FAST_CHECKIN_WKSP, VR_RESERVATIONS_WKSP; ACTION IS IF (ACMS$T_STATUS_TYPE = "G") THEN MOVE VR_FAST_CHECKIN_WKSP.ACTUAL_RETURN_DATE TO VR_VEHICLE_RENTAL_HISTORY_WKSP.ACTUAL_RETURN_DATE, VR_FAST_CHECKIN_WKSP.RETURN_ODOMETER_READING TO VR_VEHICLE_RENTAL_HISTORY_WKSP.RETURN_ODOMETER_READING; ELSE CANCEL TASK RETURNING ACMS$L_STATUS; END IF; ! ! RETRIEVE THE VEHICLE AND VEHICLE_RENTAL_HISTORY RECORDS ! PROCESSING WITH NONPARTICIPATING SERVER CALL PROCEDURE VR_FIND_VE_VRH_PROC IN VR_READ_SERVER USING VR_RESERVATIONS_WKSP, VR_VEHICLES_WKSP, VR_VEHICLE_RENTAL_HISTORY_WKSP, VR_RENTAL_CLASSES_WKSP, VR_TRANS_WKSP; ACTION IS IF (ACMS$T_STATUS_TYPE = "B") THEN CANCEL TASK RETURNING ACMS$L_STATUS; END IF; ! ! QUEUE THE TASK TO BE RUN LATER ! PROCESSING CALL PROCEDURE VR_ENQ_FAST_CHECKIN IN VR_QUEUE_SERVER USING VR_FAST_CHECKIN_WKSP; ACTION IS IF (ACMS$T_STATUS_TYPE = "G") THEN MOVE "FASTCHIN" TO VR_HIST_WKSP.TRANS_TYPE, VR_VEHICLES_WKSP.VEHICLE_ID TO VR_HIST_WKSP.VEHICLE_ID; ELSE CANCEL TASK RETURNING ACMS$L_STATUS; END IF; ! ! WRITE A RECORD OF A SUCCESSFUL CHECK IN TO THE HISTORY DATABASE ! PROCESSING CALL PROCEDURE VR_WRITE_HIST_RECORD_PROC IN VR_LOG_SERVER USING VR_HIST_WKSP, VR_RESERVATIONS_WKSP; END BLOCK; END DEFINITION; |
Because the VR_FAST_CHECKIN_TASK is joining a distributed transaction started by the agent, the root block step must use the TRANSACTION phrase.
The first processing step in VR_FAST_CHECKIN_TASK uses the reservation ID, obtained from the customer by the agent, to retrieve the reservation record. The second processing step retrieves the car history record. Because the first two processing steps perform read-only operations, neither step participates in the distributed transaction. Both steps use the NONPARTICIPATING SERVER phrase.
The third processing step calls the VR_ENQ_FAST_CHECKIN procedure to queue the VR_COMP_FAST_CHKIN_TASK.
The final processing step writes a record of the transaction into the database. If the procedure completes successfully, the task ends, and the agent calls the transaction services to commit the distributed transaction. Example 9-7 shows the COBOL procedure that the VR_FAST_CHECKIN_TASK calls to enqueue a task.
Example 9-7 Enqueuing Routine |
---|
IDENTIFICATION DIVISION. ************************************************************** PROGRAM-ID. VR-ENQ-FAST-CHECKIN. * * * Version: 01 * * Edit: 00 * * Edit dates: 16-OCT-1990 * * Authors: DIGITAL * * Called From: AGENT * * * ************************************************************** ************************************************************** * F U N C T I O N A L D E S C R I P T I O N * * * * This routine is called by the VR_FAST_CHECKIN_TASK. * * The VR_FAST_CHECKIN_WKSP is initialized by the VR_AGENT. * * The VR_COMP_FAST_CHKIN_TASK uses the information in the * * workspace to complete the checkin database functions. * * * ************************************************************** ************************************************************** * * * C O P Y R I G H T * * * * COPYRIGHT (c) 1990 BY * * DIGITAL EQUIPMENT CORPORATION, MAYNARD * * MASSACHUSETTS. ALL RIGHTS RESERVED. * * * * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND * * MAY BE USED AND COPIED ONLY IN ACCORDANCE WITH * * THE TERMS OF SUCH LICENSE AND WITH THE * * INCLUSION OF THE ABOVE COPYRIGHT NOTICE. THIS * * SOFTWARE OR ANY OTHER COPIES THEREOF MAY NOT * * BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY * * OTHER PERSON. NO TITLE TO AND OWNERSHIP OF * * THE SOFTWARE IS HEREBY TRANSFERRED. * * * * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO * * CHANGE WITHOUT NOTICE AND SHOULD NOT BE * * CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT * * CORPORATION. DIGITAL EQUIPMENT CORPORATION * * ASSUMES NO RESPONSIBILITY FOR ANY ERRORS THAT * * MAY APPEAR IN THIS SOFTWARE. * * * * DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE * * OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT * * THAT IS NOT SUPPLIED BY DIGITAL. * * * ************************************************************** ENVIRONMENT DIVISION. CONFIGURATION SECTION. ************************************************************** DATA DIVISION. ****************************************************************** WORKING-STORAGE SECTION. * * Return status to pass status to ACMS * 01 RET-STAT PIC S9(9) COMP. * * Task name * 01 TASK PIC X(24) VALUE IS "VR_COMP_FAST_CHKIN_TASK". * * Application Name * 01 APPL PIC X(7) VALUE IS "VR_APPL". * * * Queue Name * * Queue name cannot contain trailing spaces. * 01 QNAM PIC X(8) VALUE IS "VR_QUEUE". * * Flag - 0 = NOHOLD - the queued task is free to run * 1 = HOLD - the queued task is stored but may not run * 01 FLAG PIC 9(9) COMP VALUE IS 0. * * A list of workspace descriptors is sent to the queue service. * For this task, only 1 workspace is required (VR_FAST_CHECKIN_WKSP). * 1 is the number of workspaces in the list, QTE_WS_DESC is the * descriptor being sent, so the address of the address of * QTE_WS_DESC is stored. * 01 WS_DESC_LIST. 05 DES_LIST_CNT PIC S9(9) COMP VALUE 1. 05 QTE_WS_DESC_PTR POINTER VALUE IS REFERENCE QTE_WS_DESC. * * Each workspace must be described by a desriptor. 16 is the number * of bytes in the workspace VR_FAST_CHECKIN_WKSP so its address is * stored in the descriptor. * 01 QTE_WS_DESC. 05 FAST_CHECKIN_WS_SIZE PIC S9(9) COMP VALUE IS 16. 05 FAST_CHECKIN_PTR USAGE IS POINTER. ********************************************************************* LINKAGE SECTION. * COPY "VR_FAST_CHECKIN_WKSP" FROM DICTIONARY. * ********************************************************************** PROCEDURE DIVISION USING VR_FAST_CHECKIN_WKSP GIVING RET-STAT. ********************************************************************** MAIN-SECTION. SET RET-STAT TO SUCCESS. SET FAST_CHECKIN_PTR TO REFERENCE OF VR_FAST_CHECKIN_WKSP. CALL "ACMS$QUEUE_TASK" USING BY DESCRIPTOR QNAM, BY DESCRIPTOR TASK, BY DESCRIPTOR APPL, BY REFERENCE WS_DESC_LIST, BY REFERENCE FLAG GIVING RET-STAT. EXIT-PROGRAM. EXIT PROGRAM. |
Example 9-8 shows the definition of the VR_COMP_FAST_CHKIN_TASK.
Example 9-8 VR_COMP_FAST_CHKIN_TASK Definition |
---|
! ! This task is queued by the VR_FAST_CHECKIN_TASK which in turn ! is called by an ACMS agent. The agent obtains information from ! the user and sends it to the VR_FAST_CHECKIN_TASK. The ! VR_FAST_CHECKIN_TASK passes the information to the task. ! REPLACE TASK AVERTZ_CDD_TASK:VR_COMP_FAST_CHKIN_TASK USE WORKSPACES VR_FAST_CHECKIN_WKSP, VR_RESERVATIONS_WKSP, VR_RENTAL_CLASSES_WKSP, VR_VEHICLES_WKSP, VR_TRANS_WKSP, VR_VEHICLE_RENTAL_HISTORY_WKSP, VR_HIST_WKSP, VR_CONTROL_WKSP; TASK ARGUMENTS ARE VR_FAST_CHECKIN_WKSP WITH ACCESS READ; ! QTI STARTS A DISTRIBUTED TRANSACTION BEFORE BEGINNING THIS TASK. ! THIS TASK JOINS THE DISTRIBUTED TRANSACTION. SHOULD THE TASK FAIL ! FOR ANY REASON, THE QTI ABORTS THE DISTRIBUTED TRANSACTION AND STARTS ! A NEW DISTRIBUTED TRANSACTION SO THAT IT CAN TRANSFER THE FAILED ! QUEUED TASK RECORD ONTO AN ERROR QUEUE, IF ONE EXISTS. BLOCK WITH TRANSACTION NO I/O ! ! FIND THE RESERVATION RECORD. ! PROCESSING WITH NONPARTICIPATING SERVER CALL PROCEDURE VR_FIND_RES_PROC IN VR_READ_SERVER USING VR_FAST_CHECKIN_WKSP, VR_RESERVATIONS_WKSP; ACTION IS IF (ACMS$T_STATUS_TYPE = "G") THEN MOVE VR_FAST_CHECKIN_WKSP.ACTUAL_RETURN_DATE TO VR_VEHICLE_RENTAL_HISTORY_WKSP.ACTUAL_RETURN_DATE, VR_FAST_CHECKIN_WKSP.RETURN_ODOMETER_READING TO VR_VEHICLE_RENTAL_HISTORY_WKSP.RETURN_ODOMETER_READING; ELSE CANCEL TASK RETURNING ACMS$L_STATUS; END IF; ! ! RETRIEVE THE VEHICLE AND VEHICLE_RENTAL_HISTORY RECORDS. ! PROCESSING WITH NONPARTICIPATING SERVER CALL PROCEDURE VR_FIND_VE_VRH_PROC IN VR_READ_SERVER USING VR_RESERVATIONS_WKSP, VR_VEHICLES_WKSP, VR_VEHICLE_RENTAL_HISTORY_WKSP, VR_RENTAL_CLASSES_WKSP, VR_TRANS_WKSP; ACTION IS IF (ACMS$T_STATUS_TYPE = "B") THEN CANCEL TASK RETURNING ACMS$L_STATUS; END IF; ! ! COMPUTE THE BILL. ! PROCESSING WITH NONPARTICIPATING SERVER CALL PROCEDURE VR_COMPUTE_BILL_PROC IN VR_READ_SERVER USING VR_RESERVATIONS_WKSP, VR_RENTAL_CLASSES_WKSP; ACTION IS IF (ACMS$T_STATUS_TYPE = "B") THEN CANCEL TASK RETURNING ACMS$L_STATUS; END IF; ! ! COMPLETE THE CHECKIN PROCESS. ! PROCESSING CALL PROCEDURE VR_COMPLETE_CHECKIN_PROC IN VR_UPDATE_SERVER USING VR_RESERVATIONS_WKSP, VR_VEHICLES_WKSP, VR_VEHICLE_RENTAL_HISTORY_WKSP, VR_CONTROL_WKSP; ACTION IS MOVE "FSTCHKIN" TO VR_HIST_WKSP.TRANS_TYPE, VR_VEHICLES_WKSP.VEHICLE_ID TO VR_HIST_WKSP.VEHICLE_ID, VR_RESERVATIONS_WKSP.RENTAL_TOTAL_AMT TO VR_HIST_WKSP.RENTAL_TOTAL_AMT; PROCESSING CALL PROCEDURE VR_WRITE_HIST_RECORD_PROC IN VR_LOG_SERVER USING VR_HIST_WKSP, VR_RESERVATIONS_WKSP; END BLOCK; END DEFINITION; |
The task queue VR_QUEUE is marked for RMS recovery unit journaling. Therefore, the QTI starts a distributed transaction before submitting the VR_COMP_FAST_CHKIN_TASK for processing. To join the distributed transaction, the task specifies TRANSACTION on the root block step.
The first two processing steps use the reservation ID, obtained by the agent, to retrieve reservation and car records. The third processing step computes the bill. Because these three processing steps are not writing to the database, they use the NONPARTICIPATING SERVER phrase to exclude themselves from the distributed transaction.
Previous | Next | Contents | Index |