PMDF Programmer's Reference Manual


Previous Next Contents Index

1.3 Dequeuing Messages

Messages stored in PMDF's message queues are removed from those queues by dequeuing them. This is typically done by channel programs.8 When a message is dequeued, it is literally removed from PMDF's message queues and, as far as PMDF is concerned, no longer exists. This means that dequeuing a message relieves PMDF of all further responsibility for the message---the responsibility is assumed to have been passed on to another mailer, gateway, or user agent.

The message queue serviced by a program is determined from "out-of-band" information. For instance, under OpenVMS the queue to be serviced is determined through the PMDF_CHANNEL logical whose translation value gives the name of the channel to service. On UNIX and NT, the channel name is given by the PMDF_CHANNEL environment variable.

The steps taken to dequeue messages are as follows:

  1. Initialize PMDF resources and data structures with PMDFinitialize.
  2. Initialize the PMDF dequeuing subsystem with PMDFdequeueInitialize.
  3. Process all pending messages for the channel by repeatedly executing the following steps:
    1. Access a message with PMDFgetMessage. This step also reads the envelope From: address from the accessed message.
    2. Process the accessed message. The following steps are used to read the currently accessed message:
      1. the envelope To: addresses and processing flags are read by repeatedly calling PMDFgetRecipient and PMDFgetRecipientFlags;
      2. the message header lines are read by repeatedly calling PMDFreadLine or PMDFreadText until the first blank line is encountered, or by calling PMDFreadHeader to read the entire header at once; and
      3. the message body is read by repeatedly calling PMDFreadLine or PMDFreadText.
      4. any message delivery failure log can be read with repeated calls to PMDFreadFailureLog.
    3. Set the disposition of each envelope To: address with repeated calls to PMDFrecipientDisposition.
    4. Dequeue the message with PMDFdequeueMessageEnd.
  4. Close the message dequeuing subsystem with a call to PMDFdequeueEnd.
  5. Deallocate PMDF resources and data structures with a call to PMDFdone.
Note that the message is not actually dequeued until the very last processing step, 3d. This is very important: it keeps mail from being lost if the channel program fails unexpectedly, the system crashes, or other unexpected disasters occur. The message processing involved in Step 3 can be almost anything. The processing can even involve re-enqueuing the message to another channel as illustrated in Examples 1-8 and 1-9.

When the disposition of each envelope To: address is determined, it should be reported to PMDF by calling PMDFrecipientDisposition. The recognized dispositions are given in the description of the PMDFrecipientDisposition routine and are repeated below.
Symbolic name Value Description
PMDF_DISP_DEFERRED 1 Recipient address processing has failed because of a temporary problem ( e.g., network down, remote host unreachable, mailbox busy, etc.); defer processing of this address until later.
PMDF_DISP_DELIVERED 2 Recipient address was successfully delivered; generate a delivery status notification if required.
PMDF_DISP_FAILED 3 Recipient address processing has failed because of a permanent problem ( e.g., invalid recipient address, recipient over quota, etc.); no further delivery attempts should be made for this address. Generate a non-delivery notification if required.
PMDF_DISP_RELAYED 4 Recipient address was forwarded to another address or gatewayed into a non-NOTARY mail system. The message's NOTARY information was preserved - there is no need to generate a "relayed" notification message.
PMDF_DISP_RELAYED_FOREIGN 5 Recipient address was forwarded to another address or gatewayed to a non-NOTARY mail system. The message's NOTARY information was not preserved - generate a "relayed" notification message if required.
PMDF_DISP_RETURN 6 For this recipient, return the message as undeliverable; generate a non-delivery notification if required.

When PMDFdequeueMessageEnd is called, the resulting processing depends upon the disposition of the envelope To: recipient addresses as reported with PMDFrecipientDisposition. If all recipient addresses have a permanent disposition (PMDF_DISP_DELIVERED, PMDF_DISP_FAILED, PMDF_DISP_RELAYED, PMDF_DISP_RELAYED_FOREIGN, or PMDF_DISP_RETURN), then any required notifications are generated and the message is permanently removed from the processing queue. If all recipients are to be deferred PMDF_DISP_DEFERRED, then no notifications are generated and the message is left in the queue for later re-processing. If some recipients have a permanent disposition while others were deferred, then

  1. Notifications are generated for those recipients with permanent dispositions and requiring notifications,
  2. A new message is enqueued for just those recipients who were deferred, and
  3. The original message is removed from the processing queue.

If the program needs to abort message processing, it should call PMDFdequeueMessageEnd with a value of true (1) for the defer argument to that routine. This will leave the message in the processing queue for later re-processing.

In the loop represented by Step 3, PMDFgetMessage will repeatedly return each message in the current queue that requires processing until there are no more messages to be processed. Each message in the queue will only be presented once; i.e., a job will not repeatedly see a message that it has deferred. Multiple jobs can simultaneously run and process the same message queue: PMDF will automatically prevent two or more jobs from simultaneously processing the same message. When PMDFgetMessage is called, the accessed message is locked so that no other jobs can access that message. The message is unlocked when PMDFdequeueMessageEnd is called, or when the job exits (abnormally or otherwise).

Generally, programs which perform dequeue processing do not run indefinitely but rather exit after processing all messages in a specific queue. If it's necessary to write a program that never exits and does dequeue processing, then PMDFdequeueEnd, PMDFcloseQueueCache, PMDFcloseLogFile should be called after looping over every message in a message queue. When it's time to try processing the message queue again, PMDFdequeueInitialize should be called before the first PMDFgetMessage call.

Examples 1-5, 1-6, 1-8, 1-9, 1-10, and 1-11 all illustrate message dequeue processing.

Note

8 Channel programs comprise a broad class of programs that interface PMDF to other networks, mail systems (MTAs), and user agents (UAs). Gateways are an example of channel programs: channel programs which gateway or otherwise transport mail out of PMDF do so by dequeuing messages and are sometimes referred to as master channels; channel programs which gateway or otherwise transport mail into PMDF do so by enqueuing messages and are sometimes referred to as slave channels. Channel programs can also perform intermediate roles by dequeuing messages from one message queue and requeuing them to another while processing the message at the same time (e.g., converting the message body from one format to another).


Previous Next Contents Index