One answer might be the C programmer is an optimist and assumes things will always work and the Application Programmer is a pessimist and trusts nothing. Another difference is that an application programmer takes view of the system as a whole, while a C programmer just thinks about the program he is writing in isolation.
I expect most of the readers to say “I do all of these good things… it is everyone else who does not!
For example the application programmer.
- Validates the data received. Checks the presence of value in a field, and the length of a field is correct ( and does not have some additional SQL hidden on the end of a field’s value). Does not trust the length of the data – uses C function strncpy or memcpy functions (although a good C programmer should know this!)
- Knows some fields can be faked, and so cannot be relied on
- Puts out useful messages or events when a problem is detected
- The name of the detecting program and the line number
- The compile date of the code – especially useful when doing “agile” and a new version of the code is put into production every day
- The reason for the error such as the name of the field with the wrong value, and the value in hex, or the name of a missing field in the data
- The caught exception. One IBM product caught a file exception and ignored it. It then threw “internal error ” exception – that problem was very hard to diagnose!
- For messages got within sync point, uses Harden Backout – so if the program abends, and the message can be seen to have been processed before – and put on a error queue with an error code saying “Dangerous Message”
- Produces an event or message for automation, in the event of the application program stopping abnormally.
- Uses business application specific back-out and dead letter queues. Has programs which process these queues.
Counts the calls
The application programmer ensures the correct number of MQ calls are made
- Is the application long running or short running ( if short running can it be made long running)?
- Long running avoids the costs of connect/disconnect, MQOPEN and MQCLOSE
- If long running
- Connects once. If using Java – ensures the connection is saved – and not deleted when a function returns and the internal variable is finalised leading to MQDISC, (and an MQCONN for the next request).
- Opens the queues once.
- Uses MQPUT1 if many reply-to queues – uses MQOPEN, MQPUT, MQPUT if only a few queues are used.
- Explicitly uses syncpoint ( commit) where appropriate z/OS and distributed MQ have different default behaviors
- If a long running transaction periodically ( for example hourly) disconnects and reconnects. This may then connect to a different queue manager, and so spread the load across the queue managers. This resolves the problems in the following scenario. Consider QMA down for maintenance. All connections connect to QMB. Restart QMA – all connections are still connected to QMB – and stay there for the whole day.
Uses the correct persistence
Persistent messages make it easier to write applications, as MQ does more work for you.
If you want to use non persistent messages for important data then your application needs to worry about a messages getting lost, and having to resend it. Applications downstream need to be able to handle possible duplicate messages.
Most persistent messages are processed within syncpoint – the exception being audit type messages which say “I was here”. In syncpoint allows the request to be rolled back, and coordinated across resource managers such as MQ and DB2.
Non persistent messages are good candidates for getting and putting out of syncpoint.
Getting or putting persistent messages outside of syncpoint can limit throughput as on distributed MQ, access to the queue is serialised. If the message is out of syncpoint, then the queue will be locked for the duration of the log write requests. If the logging takes 5ms – you will not be able to achieve more than 200 a second.
You cannot just change message persistence from persistent to non persistent and hope it works! You need to understand the implications of the change from end to end.
Handles non zero return codes.
- Applications need logic to handle non zero return codes. For example queue manager quiescing; not authorized; messages too large for the queue.
- A good application will have logic to handle the common situations – and the logic in these paths has been written and tested.
- Someone told me about a customer application which had a block comment saying “if you get here phone John on 07808…” and return code 0!
Keeps an eye on what’s happening.
For example time the request to an external server. If it takes too long, produce an event saying so – but do not produce too many events! For example produce an event every minute or every 10 minutes saying ‘In 1 minute there were x messages taking over 2 seconds”
Uses the naming standards
Documents the program and provides information on what queues and channels are used, and what they are used for. So in 10 years time people will be able to see why decisions were made.
Documents the security requirements for the queues and the transactions and talks to the MQ systems programmer to get the policy implemented.