Chapter 6 . Building and Testing Applications

This chapter describes the following tasks:


Formatting and Converting Message Data

Computer systems from different manufacturers may format data and data structures differently. When sending messages between computers in a multivendor environment, the process of data marshaling ensures that data is interpreted properly between the sending and receiving systems.

The new self-describing messaging (SDM) feature in MessageQ Version 4.0 -allows applications to construct messages that contain information about how to -interpret the message content. Therefore, SDM performs data marshaling to handle byte order and data alignment differences between computer systems. See the Self--Describing Messaging topic for more information.

Byte Order Conversion

Computer systems use two different methods to store a single integer value as a longword. A longword, which represents 4 bytes, can be stored from highest to lowest address order or from lowest to highest.

The term endian refers to the end of the longword that the computer begins reading first. Some computers read the longword beginning with the lowest byte address, a format called little endian. Other computers read the longword starting with the highest byte address, a format called big endian.

When information is exchanged between computer systems that use different endian formats, the format must be agreed upon by the two systems. Otherwise, the target system will read the data and interpret the wrong integer value. The sender program can convert the data by reversing the order of the bytes before the data is sent over the network. Or the receiver program can reverse the order of the bytes before it interprets the integer.

The convention for sending data between dissimilar endian machines is to use network byte order (big endian format) to pack data into a message before sending it. The show buffer argument of the pams_get_msg function returns the endian format of the system that originated the message. The endian field is applicable to an integer-only format.

One way to avoid having to perform endian conversion is to convert numbers into character strings and to only use messages composed entirely of ASCII text data. While requiring more buffer space, text-only messages are always completely portable for reception on any system.

If you must format message data using numeric data types, you can use several conversion functions to convert the network byte order of the messages between systems that use different endian formats. Many systems or C compilers (including ULTRIX, VAX C, and most UNIX systems) provide the ntohl(), ntohs(), htonl(), and htons() functions. These functions convert numeric data types to or from their host internal representation into a common standard format (called network byte order) for message transmission.

If these functions are not available, a user function could be written to produce the same results. Network byte order arranges the bytes with the most significant bits at the lower addresses.

Alignment of Data Structures

In addition to converting data between different endian formats, MessageQ applications may also need to align message data structures to ensure that message content is interpreted properly by the target system. Many RISC compilers automatically perform data alignment during program compilation. When a program is compiled, data elements within a structure are aligned along natural boundaries by data type such as byte, word, or longword.

Alignment causes data elements to shift position when space is added to align the elements along these boundaries. Aligning data helps programs to run more efficiently. However, because elements are moved and space is added to the structure, alignment changes the way in which the data structure must be read.

Developers can use one of the following methods to ensure that message data structures are not changed by data alignment:

See your system documentation for more information about data formatting on your system.


Writing Portable MessageQ Applications

The best approach in developing MessageQ applications is to use portable programming techniques that allow the application to run in many different computing -environments. Writing portable applications reduces development and maintenance costs as applications are required to run on systems from many vendors.

The following suggestions for developing MessageQ applications simplify porting applications to all industry-leading platforms:

Only OpenVMS systems allow applications to omit the trailing arguments in a function call if they are not required. All other MessageQ implementations require that each argument in a MessageQ function be specified. Arguments that are not required by the application should be specified by passing a value of zero.


Compiling and Linking MessageQ Applications

This topic describes how to build your MessageQ applications for UNIX, -Windows NT, and OpenVMS environments. The following sections describe:

Using MessageQ Include Files

To use MessageQ API functions and other standard features in your application, reference the MessageQ include files at the beginning of your application program. Table 6-1 describes the contents of each MessageQ include file. The -include files can be used with both the C and C++ programming languages.

Table 6-1 C Include File Cross-Reference

File Name Comments Description

p_entry.h

Entry point definitions

Declares the entry point for all MessageQ API calls.

p_proces.h

Process definitions

Defines the queue numbers symbolically to identify other queues in the MessageQ message queuing system.

p_group.h

Group definitions

Defines the group numbers symbolically to identify other groups in the MessageQ message queuing system.

p_typecl.h

Type and class definitions

Contains the symbolic names for all standard MessageQ type and class definitions. On OpenVMS systems you can add user-defined type and class codes to this file. On UNIX, Windows NT, and OS/2 systems you must create a separate include file for user-defined type and class codes.

p_return.h

Return code definitions

Contains the compile time symbols for MessageQ return status codes.

p_symbol.h

Global symbol definitions

Defines symbols used by MessageQ to control features such as message selection and recoverable messaging.

p_msg.h

Message API definitions

Declares the data structures for all MessageQ message-based services.

All implementations of MessageQ software access the C language include files in the same manner. Listing 6-1 shows the recommended method of specifying portable #include statements in C.

Listing 6-1 Recommended #include Statements for MessageQ Applications
#include <errno.h>
#include <stdio.h>
/* Include PAMS-specific definition files. */
#include <p_entry.h> /* PAMS function type declarations */
#include <p_proces.h> /* Known Queue number definitions. */
#include <p_group.h> /* Known group number definitions. */
#include <p_typecl.h> /* Generic type/class definitions. */
#include <p_return.h> /* PAMS func return status definitions*/
#include <p_symbol.h> /* Generic PSEL/PDEL definitions. */
#include <p_msg.h> /* Message type declarations */

Portable code requires a conditional compile (such as #if/#endif when programming in C) around the include statements. For an example of how to incorporate include files into your application, refer to the sample programs in the examples directory of your MessageQ media kit.

To use MessageQ functions and other standard features in an application program, the program references the MessageQ include files. Table 6-2 lists the location of the standard MessageQ include files for the C programming language.

Table 6-2 MessageQ Programming Language Support

Platform Location

UNIX

/usr/include directory

Windows NT

directory selected during installation

OS/2

directory selected during installation

OpenVMS

DMQ$USER:


MessageQ for OpenVMS systems uses the portable include file names for the C programming language. For other programming languages, MessageQ uses another set of names for the include files. The OpenVMS include files for all other languages are contained in a single library called DMQ.TLB. The logical name DMQ$USER points to the directory containing DMQ.TLB.

Include files on OpenVMS systems are available for several programming languages. The include files begin with PAMS_XXX_ where XXX is a 1- to 3-letter designation identifying the programming language as follows:

MessageQ for OpenVMS systems uses two different include files for return code symbols. Compile-time symbols are contained in the PAMS_XXX_RETURN_STATUS_DEF file. Link-time symbols are contained in the PAMS_ XXX_RETURN_STATUS file. Include one of the following in your application program:

Programming Language Support

Table 6-3 shows the languages supported by MessageQ products:

Table 6-3 Supported Programming Languages

Product Supported Languages

MessageQ for UNIX
MessageQ UNIX Client

C, C++

MessageQ for Windows NT
MessageQ Windows Client

C, C++, Visual Basic, Powerbuilder

MessageQ for OpenVMS
MessageQ OpenVMS Client

Ada, Basic, Bliss-32, C, C++, Cobol, Fortran, Macro-32, PL/I, Pascal

MessageQ for OS/2
MessageQ OS/2 Client

IBM C/Set++ Version 2.1
IBM Visual Age C++ Version 3.0
Symantec C/C++ compiler Version 6.2
Borland C++ for OS/2 Version 2.0

MessageQ MVS Client

C, Cobol

Connecting to the MessageQ Environment

Before running a program that uses MessageQ, you must set the environment to identify the message queuing bus and the message queuing group with which the program will be associated.

For UNIX and Windows NT, MessageQ uses the following environment variables:

DMQ_BUS_ID

Sets the bus ID for the application.

DMQ_GROUP_ID

Sets the group ID for the application.

To set environment variables that designate bus and group ID using csh syntax on UNIX systems, enter the following commands:

#  setenv DMQ_BUS_ID bus_id
# setenv DMQ_GROUP_ID group_id

To set environment variables that designate bus and group ID using command line syntax on Windows NT systems, enter the following commands:

set DMQ_BUS_ID bus_id
set DMQ_GROUP_ID group_id

MessageQ for OpenVMS enables you to tailor your run-time environment using OpenVMS logical names. You can use the command DMQ$SET_LNM_TABLE to place the required logical name table into the user's logical name search tree. This command procedure requires two parameters: the bus ID and the group ID.

Enter the following command to execute this procedure:

$ @MY_DMQ_DISK:[DMQ$V40.EXE]DMQ$SET_LNM_TABLE bus_id group_id

If the user frequently uses a particular bus and group, the invocation of the command procedure can be added to the user's LOGIN.COM file. The system manager can define the symbol DMQ_SET to simplify this command procedure. See the MessageQ Installation and Configuration Guide for OpenVMS for more information.

Table 6-4 describes logical names that are useful for testing, monitoring, and debugging operations. See the MessageQ Installation and Configuration Guide for OpenVMS for a complete list of MessageQ logical names.

Table 6-4 MessageQ for OpenVMS Logical Names

Logical Name Description

DMQ$DCL_NUMBER

This logical name is a base 10 queue number that overrides the queue number submitted to pams_attach_q.

DMQ$EXIT_PURGE

This logical name controls the purging of pending messages when the program exits. When defined as NO, it disables the MessageQ exit handler from purging all primary and secondary queues attached to the process. This feature has no effect on pending recoverable messages because they are always requeued when pams_attach_q is called to attach to the queue.

DMQ$DEBUG

Some special features are incorporated into MessageQ to aid in debugging. The logical name DMQ$DEBUG can be set to one of the following states by using the DCL DEFINE command:

DMQ$HEADERS

This logical name controls the printing of MessageQ headers on the SYS$OUTPUT device; for example, the terminal. When this logical name is defined, MessageQ header information is displayed when messages are sent to or received from this process.

DMQ$TRACE_OUTPUT

This logical name defines the location where trace information is logged.

Compiling and Linking Applications

This topic describes how to compile and link your MessageQ application on UNIX, Windows NT and OpenVMS systems.

The following sections describe:

UNIX Makefile

UNIX systems use a makefile to incorporate the commands for compiling and linking application programs. Listing 6-2 shows a sample makefile for running a MessageQ for UNIX application. The sample makefile, with the client and server programs, is included in the root directory of your MessageQ for UNIX media kit.

Listing 6-2 UNIX Makefile
# library to link against libdmq.a in /usr/lib
LIBS   =   -ldmq
# compiler flags include debugging symbols,  don't use prototypes 
CFLAGS =   -g -D_NO_PROTO
# build both the client and the server
all:       s_client s_server
# client depends on s_client.o s_getopt.o
s_client:  s_client.o s_getopt.o
cc $(CFLAGS) s_client.o s_getopt.o $(LIBS) -o s_client
# server depends on s_server.o s_getopt.o
s_server:  s_server.o s_getopt.o
cc $(CFLAGS) s_server.o s_getopt.o $(LIBS) -o s_server

When building MessageQ applications on the Digital UNIX platform, you must link your applications against the library libots.a in addition to the MessageQ library. For example:

# cc myapp.c -ldmq -lots - myapp

Windows NT Makefile

The MessageQ for Windows NT API is implemented in dynamic link libraries (DLLs). The directory containing the DLLs must be in your path when you run your applications. All MessageQ for Windows NT API functions are exported by DMQ.DLL and defined in the import library DMQ.LIB. Other Windows NT products that can call DLLs can also call MessageQ API functions.

MessageQ for Windows NT systems provides full support for Windows NT multithreading. Each thread in the MessageQ process has an independent MessageQ context, which means a queue that is attached in one thread is not available to another thread in the same process.

All threads must attach their own queues via the pams_attach_q function. When a program thread issues a pams_exit call, it does not affect queues attached by other threads in the same process. Multiple threads in one application can communicate via MessageQ exactly as though they were in separate processes.

The example Windows NT makefile, x_make.mak, provides a good starting point for building your own makefiles. To link with MessageQ for Windows NT systems, you need only include DMQ.LIB when you link. The following example shows a sample makefile for running a MessageQ for Windows NT application. Listing 6-3 makefile is included in the examples directory of your MessageQ for Windows NT media kit.

Listing 6-3 Windows NT Makefile
#
# x_make.mak: Example makefile for MessageQ applications.
# This makefile builds the "simple client" and
# "simple server" applications.
#
# execute this file with NMAKE as follows:
#
# NMAKE -f example.mak DMQ=drive:\dir\
#
# where "drive" is the drive where MessageQ is installed and
# "directory" is the directory where MessageQ is installed.
#
#
!include <ntwin32.mak>
BIN=.\
DLIB=$(DMQ)
SRC= $(DMQ)
OBJ=.\
INCDIRS= /I $(DMQ)
I_FILES= p_return.h p_entry.h p_symbol.h
ALL : $(BIN)s_client.exe $(BIN)s_server.exe
$(BIN)s_client.exe : s_client.obj s_getopt.obj
$(link) $(conflags) \
-out:$(BIN)s_client.exe \
s_client.obj s_getopt.obj \
$(DLIB)dmq.lib \
$(conlibs)
$(BIN)s_server.exe : s_server.obj s_getopt.obj 
$(link) $(conflags) \
-out:$(BIN)s_server.exe \
s_server.obj s_getopt.obj \
$(DLIB)dmq.lib \
$(conlibs)
s_server.obj : $(SRC)s_server.c $(I_FILES)
$(cc) $(cflags) $(cvars) $(SRC)s_server.c $(INCDIRS)
s_client.obj : $(SRC)s_client.c $(I_FILES)
$(cc) $(cflags) $(cvars) $(SRC)s_client.c $(INCDIRS)
s_getopt.obj : $(SRC)s_getopt.c $(I_FILES)
$(cc) $(cflags) $(cvars) $(SRC)s_getopt.c $(INCDIRS)

OpenVMS Build Procedure

This topic describes how to compile and link MessageQ applications on OpenVMS systems. The MessageQ for OpenVMS media kit includes a sample command procedure for compiling and linking MessageQ applications. Listing 6-4 shows the sample build file included in the examples directory.

Listing 6-4 Example OpenVMS Build Procedure
$!===============================================================
$! Standardized examples build procedure (V1.0-00)
$!
$! File: X_BUILD.COM
$!
$! Params: none
$!===============================================================
$
$ ss$_badparam = 20
$ ss$_nopriv = 36
$ ss$_abort = 44
$ cc_alpha = "/stand=vaxc/debug/noopt/lis"
$ cc_alpha_strict = "/stand=relaxed/debug/noopt/lis"
$ cc_vax = "/stand=portable/debug/noopt/lis"
$ wl = "write sys$output"
$
$
$ on warning then exit 4
$ on control_y then exit 'ss$_abort'
$
$ a = f$edit(f$getsyi("ARCH_NAME"), "UPCASE")
$ if f$locate("''a'", "ALPHA") .le. f$length("''a'")
$ then
$ sys_type = "Alpha"
$ alpha = "YES"
$ def_c_sw = cc_alpha + "/include=dmq$user:"
$ else
$ sys_type = "VAX"
$ alpha = "NO"
$ def_c_sw = cc_vax + "/include=dmq$user:"
$ endif
$
$ ASK_C_SW:
$ if "''p1'" .eqs. ""
$ then
$ inquire p1 "Enter C compile switches [D:''def_c_sw']"
$ if p1 .eqs. "" then p1 = def_c_sw
$ endif
$ c_sw = "''p1'"
$
$ wl ""
$ wl "------- Build Parameters -------"
$ wl " CC switches: ''c_sw'"
$ wl " System type: ''sys_type'"
$ wl ""
$
$ call CC x_attnam
$ call CC x_attnum
$ call CC x_atttmp
$ call CC x_basic
$ call CC x_exit
$ call CC x_get
$ call CC x_getall
$ call CC x_getem
$ call CC x_getpri
$ call CC x_getsel
$ call CC x_getsho
$ call CC x_getw
$ call CC x_locate
$!** call CC x_putdlj
$ call CC x_putslf
$ call CC x_recovr
$ call CC x_select
$ call CC x_shopnd
$ call CC x_timer
$ DONE:
$ wl ""
$ wl "Finished building MessageQ standard examples"
$ exit
$
$!================================================================
$
$ ! p1 = program to compile
$
$ CC: subroutine
$ on warning then exit 4
$ on control_y then exit 'ss$_abort'
$
$ wl "Building ''P1'..."
$
$ if f$search("''p1'.obj") .nes. "" then delete/nolog 'p1'.obj.*
$ if f$search("''p1'.lis") .nes. "" then delete/nolog 'p1'.lis.*
$ if f$search("''p1'.exe") .nes. "" then delete/nolog 'p1'.exe.*
$ if f$search("''p1'.map") .nes. "" then delete/nolog 'p1'.map.*
$ if f$search("''p1'.dia") .nes. "" then delete/nolog 'p1'.dia.*
$
$ cc'c_sw' 'p1'
$
$ if f$search("''p1'.obj") .nes. ""
$ then
$ link 'p1',dmq$lib:dmq/opt
$ exit
$ endsubroutine

MessageQ for OpenVMS allows two kinds of application linking: linking with the run-time library (RTL) and linking with the object library. The MessageQ run-time libraries must be installed before linking applications.

Linking with the Run-Time Library

The run-time library (RTL) is the standard form of linking application modules with the MessageQ environment. The files required for linking with MessageQ are located in two areas: DMQ$LIB and DMQ$USER. The DMQ$LIB area contains the site-independent files and the DMQ$USER area contains the site-specific files that you or your MessageQ system manager customize.

To link MessageQ applications, use the DMQ$LIB:DMQ/OPT switch in your linker command line. Use the following command to link your application:

$ LINK SAMPLE_C, DMQ$LIB:DMQ/OPT

The options file contains all the commands needed to connect to the current version of the MessageQ RTL. RTLs are OpenVMS run-time libraries that allow code -sharing between numerous simultaneous users of MessageQ. Using RTLs saves memory, disk space, and link time.

Linking with the Object Library

You can link your MessageQ program using the MessageQ object library -instead of the RTL. Using this method, each MessageQ program is built with its own copy of the MessageQ procedures. You can also link with the object library and with partial run-time libraries for protected code and MessageQ Script Facility code.

To link with the object library, use the DMQ$LIB:DMQ$OLB/OPT switch in your linker command line. Enter the following command to link your application:

$ LINK SAMPLE_C, DMQ$LIB:DMQ$OLB/OPT

Note that you may also need to include various language-specific run-time libraries or object libraries depending upon how your OpenVMS system manager has installed your layered languages.

Note: Use object library linking when you need an OpenVMS traceback.

Running a MessageQ Application

Before running a program that uses MessageQ, you must set the environment to identify the message queuing bus and the message queuing group environment with which the program will be associated. See the Connecting to the MessageQ Environment topic for information on how to set environment variables.

To run a UNIX program in the background, enter the following command:

#  myprog &

where:
myprog is the name of your program.

Running an OpenVMS Program as a Detached Process

You can run a detached process with or without a DCL context. If you choose to run your process without a DCL context, you can invoke the command procedure DMQ$EXE:DMQ$COPY_LNM_TABLE to copy all the necessary logical names into the group or system logical name table. The detached process will then have access to the logical names defined for MessageQ.

If the process is to be run with DCL context, you can invoke the command procedure DMQ$SET_LNM_TABLE before running the image. The command procedure DMQ$DETACH_PROCESS in DMQ$EXE is an example of invoking DMQ$SET_LNM_TABLE and running a detached process. Listing 6-5 shows a sample command procedure fragment that runs LOGINOUT.EXE and uses the command procedure DMQ$DETACH_PROCESS to run the detached process.

Listing 6-5 Command Procedure to Run as a Detached Process
.
.
.
$ write sys$output "...Starting MY_IMAGE.EXE"
$ startup_file = "START_TEMP_" + f$getjpi("","PID") + ".COM"
$ create/owner='f$user()' 'startup_file'
$ open/append startup 'startup_file'
$ write startup "$ @DMQ$EXE:DMQ$DETACH_PROCESS 1 1 MY_IMAGE.EXE DMQ$EXE"
$ close startup
$ run sys$system:loginout.exe -
/input = 'startup_file' -
/output = MY_PROCESS.LOG -
/error = 'f$trnlnm(""sys$error"")' -
/process_name = MY_PROCESS -
/priority = 4 -
/uic = 'f$user()' -
/io_buffered = 100 -
/io_direct = 100 -
/buffer_limit = 200 -
/working_set = 500 -
/maximum_working_set = 700 -
/extent = 2000 -
/page_file = 10000 -
/ast_limit = 100 -
/buffer_limit = 100 -
/enqueue_limit = 100 -
/file_limit = 50 -
/queue_limit = 100
.
.
.

Running Existing MessageQ Applications Under Version 4.0

To run existing applications under MessageQ Version 4.0, you must begin by converting your group initialization files to the Version 4.0 format and restarting your message queuing groups. Table 6-5 describes whether or not existing applications need to be recompiled or relinked to run under MessageQ Version 4.0:

Table 6-5 Running Existing MessageQ Applications Under Version 4.0

Product Running Existing Applications

MessageQ for UNIX

To take advantage of MessageQ Version 4.0 features, you must recompile and relink your applications.

MessageQ for OpenVMS
MessageQ for OS/2

Applications that are linked with the MessageQ run-time library (DMQ.OPT) do not have to relink to use MessageQ Version 4.0. However, because the LOCATE_REP response message is now RISC-aligned, you should recompile and relink your application to take advantage of the change.

MessageQ for Windows NT

MessageQ Version 3.2 or earlier applications do not need to be recompiled or relinked. However, to take advantage of the new MessageQ Version 4.0 features, you must recompile and relink your applications.

MessageQ Windows Client

When upgrading to MessageQ Version 4.0 from any previous version of MessageQ, we recommend that you recompile and relink your application to take advantage of new features.

Running Applications Under Windows 95 or NT Systems

Applications built on Windows Version 3.1 systems (16-bit applications) may run on Windows 95 or NT systems. However, there may be some restrictions, for example, PATHWORKS for Windows NT does not support 16-bit applications. We recommend that you recompile and relink your applications under Windows 95 or Windows NT systems.

To convert a 16-bit application to a 32-bit application on Windows 95 or NT systems, you must recompile and relink your application with the 32-bit import library, DMQCL32.LIB.

Linking an Application from a MessageQ Client System to a MessageQ Server System

The following information describes how to link applications between MessageQ client and server systems on Windows, UNIX, and OpenVMS platforms.

Windows Systems

On Windows systems, you have a choice of using static or dynamic linking. Applications that use static linking need to be linked with a specific import library to resolve external function calls. Client applications use the import library DMQCL32.LIB (assuming the application is 32-bit), and server applications use the import library DMQ.LIB.

Another linking method is dynamic run-time linking. Load either the file dmq.dll or dmqcl32.dll at runtime. You need to structure your application to decide which DLL to use. You can do this by setting an ini file, a Registry entry, or a command line argument. With dynamic run-time linking, you do not need to rebuild your application when changing from client systems to server systems, or vice versa.

UNIX Systems

On UNIX systems, applications must use static linking with specific libraries. Client applications must use libdmqcl.a (TCP/IP only) or libdmqcldnet.a (TCP/IP or DECnet). Server applications must use libdmq.a. You need to rebuild your application and link with the file libdmq.a, instead of libdmqcl.a or libdmqcldnet.a.

OpenVMS Systems

On OpenVMS systems, you typically build your application against the run-time -library (RTL). Both client and server applications use the logical name -DMQ$ENTRYRTL to identify which RTL is used. You only need to execute DMQ$EXE:DMQ$SET_LNM_TABLE<bus><group> to select the server RTL. No rebuild is required.

Applications can also statically link against the server or client OLB. You will need to relink your application when changing from client to server.

Testing Return Status

Operating systems have different rules concerning what return status indicates a failure and what indicates a success. Under the OpenVMS system, a returned value indicates an error if the low bit is clear (an even number), and a success if the bit is set (an odd number). UNIX based systems typically classify values below zero as failure. Furthermore, systems can use different status values for the same status condition.

Portable programs must use a set of error-checking rules for all environments. For MessageQ software, the following rules exist for all supported systems:

PAMS_ _SUCCESS.

Listing 6-6 shows how to test for a return status on any MessageQ platform.

Listing 6-6 Portable Code for Testing Return Status
EXAMPLE 1 - Simple test for success or failure
status = pams_put_msg(msg_area, pri, target, class, type, del,
msize, 0,0,0,0);
if ((status & 1) == 0)                       /* Successful? */
{
printf("%Unexpected error %d returned\n", status);
exit(1);
}

EXAMPLE 2 - Testing for various conditions
status = pams_put_msg(msg_area, pri, target, class, type, del, msize, 0,0,0,0);
if (status != PAMS__SUCCESS)
{
if (!(success & 1))
{
printf("%Unexpected error %d returned\n", status);
exit(1);
}
    if (status == PAMS__JOURNAL_ON) printf("Journaling enabled\n");
/* Successful, and notification that journaling was enabled */
}
/* Continue processing */
EXAMPLE 3 - Using case statements
status = pams_put_msg(msg_area, pri, target, class, type, del,
msize, 0,0,0,0);
switch (status)
{
    case PAMS__SUCCESS :
break;

case PAMS__JOURNAL_ON :
printf("Journaling enabled\n");
break;
    case PAMS__PAMS_DOWN :
printf("Message bus is down\n");
exit(1);
    case else :
printf("PAMS call returned unknown error %d, aborting!\n",
status);
exit(1);
}
/* Continue processing */

MessageQ allows OpenVMS systems to automatically translate return status codes in textual messages when an application program exits. To enable this feature, enter the following command before running an application program:

$ SET MESSAGE DMQ$MSGSHR

If your application aborts during testing, it is useful to have OpenVMS traceback information. The use of the MessageQ object library and the inclusion of symbols in the executable (via the /DEBUG switch in the compile step) add to the information that is returned during traceback. If you link your application with the MessageQ RTLs, the traceback line number information is lost. To get a complete traceback, the image must be linked using the object library described in Linking with the Object Library.


Using the MessageQ Test Utility

Using a graphical or character-cell interface, the MessageQ Test utility allows developers to send and receive messages between applications to:

The MessageQ Test utility enables application developers to interactively attach to a permanent or temporary queue, read messages from a script file or available interprocess messages, and pass messages to a defined target queue. Messages sent or received using the Test utility can be previewed using its message display or the echo feature of the Script Facility. The Test utility is available on UNIX, Windows NT, and OpenVMS systems.

To invoke the Test utility using the Motif user interface on UNIX systems, set the environment variables for the bus and group ID and enter the command:

dmqtestm

To invoke the Test utility using the Motif user interface on OpenVMS systems, enter the command dmqtestm after defining the symbol as follows:

dmqtestm:==$dmq$exe:dmqtestm

To send a message, use the pull-down menus to enter the appropriate values for the required and optional arguments to the pams_put_msg function.

You can also use the Test utility to display the information received by the pams_get_msg function. Messages display on the screen to inform you when queues are attached, when messages are sent and received, and when queues are detached.

To invoke the Test utility on Windows NT systems, enter the following commands:

set DMQ_BUS_ID bus_id
set DMQ_GROUP_ID group_id
dmqtestw

To invoke the character-cell user interface on UNIX systems, set the environment variables for the bus and group ID and then enter the following command:

dmqtestc

To access the character-cell Test utility on OpenVMS systems, choose the Test option from the MessageQ main menu. The system prompts you for the following information:

Enter a setting at each system prompt or press Return to accept the default settings. Table 6-6 shows the default settings for using the Test utility.

Table 6-6 Default Settings

Setting Default Value

send_class

1

send_type

-100

send_priority

0

rcv_priority

0 (all priorities)

rcv_timeout

5 seconds

delivery

PDEL_MODE_NN_MEM


Debugging MessageQ Applications

MessageQ offers a feature called tracing to log internal messaging events to a file as they happen. You can use this file to diagnose application failures as you debug your application. It is important to consider that message tracing generates a high volume of output; therefore, you should only enable tracing for diagnostic purposes in the event of a problem.

Tracing Messages on UNIX Systems

Some special features are incorporated into MessageQ to aid in debugging. The PAMS_TRACE environment variable allows you to enable tracing to MessageQ callable services. To enable PAMS_TRACE on your system, enter the following command:

# setenv PAMS_TRACE 1

MessageQ logs trace information in the event log file. Following is the trace -information for a pams_put_msg call with a 30-second timeout from source 1.1 to -target queue 1:

PAMS:PAMS-Timeout was ZERO, using 30 seconds 
PAMS:PAMS-****** sending message ******
PAMS:PAMS-Source :, 65537 (10001)
PAMS:PAMS-Target :, 1 (1)
PAMS:PAMS-Type / Class:, 6488162 (630062)
PAMS:PAMS-Delivery :, 39 (27)
PAMS:PAMS-UMA :, 5 (5)
PAMS:PAMS-Resp Q :
PAMS:PAMS-******************************
PAMS:PAMS-PAMS_put_cleanup

To disable PAMS_TRACE, enter the following command:

# unsetenv PAMS_TRACE

Tracing Messages on Windows NT Systems

MessageQ for Windows NT systems provides an execution tracing facility for diagnostic purposes. Trace output is sent to the Event Watcher process. Tracing is enabled by setting environment variables using the following command:

SET PAMS_TRACE=value

where value is an arbitrary value.

To disable a trace, set the variables to a null value, as follows:

SET PAMS_TRACE=

You can check your environment variables at any time by entering SET at the -command line.

Tracing Messages on OpenVMS Systems

On OpenVMS systems, you can activate tracing using the DMQ$DEBUG logical name. Once tracing is enabled, you can direct trace output using the DMQ$TRACE_OUTPUT logical name. For more detailed information about how to troubleshoot MessageQ errors on OpenVMS systems, see the MessageQ I-nstallation and Configuration Guide for OpenVMS.


Controlling Message Flow

When the message queuing environment becomes congested, MessageQ lets you control the flow of messages by setting environment variables that restrict messaging rates on a per-process basis.

Note: This feature is available only on MessageQ for UNIX.

MessageQ uses a congestion control algorithm to reduce the number of messages being enqueued, which allows the system to process the backlog of messages.When the congestion condition subsides, MessageQ gradually raises the rate of message flow back to the maximum flow rate set for the queue.

The rules for enforcing congestion control are as follows:

Table 6-7 lists the congestion control environment variables for MessageQ for UNIX systems.

Table 6-7 Environment Variables for Controlling Message Flow

Environment Variable Description

DMQ_FLOW_MAXIMUM

Maximum number of messages per second a process can enqueue during a period of congestion. The default value is set to 1000 messages per second.

DMQ_FLOW_MINIMUM

Minimum number of messages per second a process can enqueue during a period of congestion. MessageQ will always allow you to enqueue at least this number of messages per second. The default value is set to 10 messages per second.

DMQ_FLOW_INTERVAL

Interval at which MessageQ checks message flow and makes adjustments to the current flow rate. The value is expressed in milliseconds. The default value is set to 250 milliseconds.

DMQ_FLOW_INCREASE

Number of messages per second to increase the flow rate at the current interval after a congestion period has subsided. The default value is set to 10 messages.

DMQ_FLOW_DECREASE

Percent reduction of the current flow rate to apply at each interval during periods of congestion. The value must be specified as a real number in the range (0.0 to 1.0). If the value is set to zero, then the maximum flow rate for the given process is equal to the flow maximum as defined by the environment variable DMQ_FLOW_MAXIMUM, and is not adjusted downward at each flow interval.
The default value is set to 0.25 intervals.

To specify congestion control for an application, use the following syntax to set the appropriate environment variable prior to starting the application:

C shell

setenv DMQ_FLOW_MAXIMUM 500

Bourne shell

DMQ_FLOW_MAXIMUM=500
export DMQ_FLOW_MAXIMUM

Because the environment variables are set on a per-process basis, you can set different values for each application in the environment.