Skip to content

Distribute document (synchronous or asynchronous)

clsPrint.distributeDocument is a single public entry point with two mutually exclusive execution modes controlled by the Asynchronous property: a direct SOAP call to xPression, or a transactional message placed on an MSMQ queue for later processing by a separate consumer. Both modes carry the same package, XML, printer, delivery, and imaging metadata; only the transport differs.

Field Value
Operation ID OP-PRT-03
Trigger Caller invokes clsPrint.distributeDocument(package, xml) (directly, or through ReportBase.Distribute, see Distribute report)
Inputs Package name, report XML payload, and the printer, plex mode, copies, scale mode, output profile, import info, email info, fax info, deferred-print info, and application name already set on the clsPrint instance
Outputs Boolean True returned after the synchronous call or the queued send completes
Primary components clsPrint.distributeDocument (public overload and private worker), clsPrint.StartMQTransaction, clsPrint.EndMQTransaction
Entry point Services\SAIF.Services.Printing\clsPrint.vb

Steps

  1. The caller invokes distributeDocument(inPackage, inXML). Package is normalized (trailing .pkg stripped) (BR-007) and XML is stored.
  2. The public overload calls the private, parameterless distributeDocument() worker, which branches on Asynchronous (BR-001).
  3. Synchronous path (Asynchronous = False). The worker calls m_Xpresso.distributeDocument, passing the package, XML, printer, plex mode, copies, scale mode, output profile, serialized import info, email info, fax info, IDM path, a fixed PaperTray.Tray2 tray selection, deferred-print info, and application name directly to the xPression SOAP service.
  4. Asynchronous path (Asynchronous = True). The worker prepares and sends a transactional MSMQ message instead of calling xPression directly (BR-002):
  5. If m_Queue has not been created yet, the worker opens a MessageQueue for the configured documentMSMQPath.
  6. The worker populates a CompositeRequestClass with package name, XML, printer, plex mode, copies, scale mode, format, output profile, import info, email info, fax info, the resolved IDM path, and deferred-print info.
  7. The request object is wrapped in a Message using BinaryMessageFormatter.
  8. If the caller had already started a transaction via StartMQTransaction (m_TxnStarted = True), the worker sends the message on that existing transaction.
    • If m_TxnStarted is not yet true, the worker calls StartMQTransaction itself, sends the message, and calls EndMQTransaction(True) to commit.
  9. On failure: EndMQTransaction(False) aborts the transaction before the exception is re-thrown.
  10. Both paths return True after their respective transport step completes without throwing.

Process flow

The following diagram visualizes the branch between the synchronous and asynchronous distribution paths.

flowchart TD
    Start([Caller invokes distributeDocument]) --> Norm[Normalize package name]
    Norm --> Mode{Asynchronous flag?}
    Mode -->|False| Sync[Call xPression<br>distributeDocument SOAP method]
    Mode -->|True| Queue{MessageQueue open?}
    Queue -->|No| Open[Open MessageQueue<br>for documentMSMQPath]
    Queue -->|Yes| Build
    Open --> Build[Build CompositeRequestClass<br>and wrap in Message]
    Build --> TxnCheck{Transaction already<br>started by caller?}
    TxnCheck -->|Yes| SendExisting[Send on existing transaction]
    TxnCheck -->|No| StartTxn[StartMQTransaction]
    StartTxn --> SendNew[Send message]
    SendNew --> Commit[EndMQTransaction True]
    SendExisting --> Done
    Commit --> Done([Return True])
    Sync --> Done
    Build -.->|Exception| Abort[EndMQTransaction False<br>re-throw]

Failure and edge-case behavior

  • Any exception during the asynchronous path's queue-open, build, or send steps triggers EndMQTransaction(False) before the exception is re-thrown; the caller still sees the original exception, not a swallowed failure (BR-002).
  • The synchronous path does not catch exceptions from m_Xpresso.distributeDocument; a SOAP fault propagates directly to the caller.*
  • The tray selection for the synchronous xPression call is hard-coded to PaperTray.Tray2 and is not configurable through any public property.*
  • If a caller starts a transaction with StartMQTransaction but never sends a message and never calls EndMQTransaction, the transaction remains open until the next asynchronous distribution call reuses it or the object is discarded.*

Note: Statements marked with * were inferred from code structure, naming conventions, or contextual evidence where direct confirmation was not available in source artifacts. Statements marked with ** could not be confirmed; treat as unknown until verified.

Sources

  • Services\SAIF.Services.Printing\clsPrint.vb