Reputation: 1079
I am working on a legacy system and have been tasked with modifying a Visual Basic API that is using mq series (now called IBM websphere) to send and receive data from a mainframe system. My network admin has informed me that he sees 97 connections from the API. At the queue manager level, max channels is set to 100. He says that is fine but that the problem is that the API makes a client channel connection but never releases it. I would assume there must be a close() action that I can execute once I retrieve the response from the queue but I do not know what the syntax would be. This is the code that I execute to send and receive data:
Dim passedmqRequest = mqRequest
Dim Session_mq_put_array As Object
Dim Session_mq_get_array As Object
Dim Session_MqResponse As String = ""
Dim Session_error_code As String = ""
Dim Session_plan_id As String = Mid(passedmqRequest, 15, 4)
Dim ipAddress As String = "xxx.xxx.xxx.xxx"
Dim mq_get_error As String = "N"
Dim mq_put_array(2) As String
Dim mq_get_array(2) As String
Dim Response_queue As String = ""
Dim Response_queue_mgt As String = ""
' send messages to TOSSMQT1
Response_queue = "ARI.GW1TEST.RESPONSES"
Response_queue_mgt = "ARIT"
mq_put_array(0) = "ARI.TEST.QUEUE"
Response_queue = "ARI.TEST.RESPONSES"
mq_put_array(1) = "VRU4300b"
mq_put_array(2) = "SVRCONN//" & ipAddress & "(1414)" '* internal
mq_put_array(2) = "SVRCONN//" & ipAddress & "(1414)" '* internal
Session_mq_put_array = mq_put_array
mq_get_array(0) = "ARI.TEST.HOST.RESPONSES"
mq_get_array(1) = "VRU4300b"
mq_get_array(2) = "SVRCONN//" & ipAddress & "(1414)" '* internal
mq_get_array(2) = "SVRCONN//" & ipAddress & "(1414)" '* internal
Session_mq_get_array = mq_get_array
Dim CmdArgs() As String
CmdArgs = Session_mq_put_array
Dim CmdResponse() As String
CmdResponse = Session_mq_get_array
Dim mqQMgr As MQQueueManager '* MQQueueManager instance
Dim mqQueue As MQQueue '* MQQueue instance
Dim responseQueue As MQQueue
Dim mqMsg As MQMessage '* MQMessage instance
Dim responseMSG As MQMessage
Dim mqPutMsgOpts As MQPutMessageOptions '* MQPutMessageOptions instance
Dim queueName As String '* Name of queue to use
Dim responsequeueName As String '* Name of response queue to use
Dim message As String '* Message buffer
Dim mqError As String = ""
queueName = CmdArgs.GetValue(0)
responsequeueName = CmdResponse(0)
'*
'* Try to create an MQQueueManager instance
'*
Dim channelDefinition As String = CmdArgs.GetValue(2)
Dim channelName As String = ""
Dim transportType As String = ""
Dim connectionName As String = ""
Dim separator As Char() = "/"
Dim parts As String()
Try
'* queue name, queue manager name, channel definition all provided
'* Break down the channel definition,
'* which is of the form "channel-name/transport-type/connection-name".
channelDefinition = CmdArgs.GetValue(2)
parts = channelDefinition.Split(separator)
If (parts.Length > 0) Then
channelName = parts(0)
End If
If (parts.Length > 1) Then
transportType = parts(1)
End If
If (parts.Length > 2) Then
connectionName = parts(2)
End If
mqQMgr = New MQQueueManager(CmdArgs.GetValue(1), channelName, connectionName)
Try
mqQueue = mqQMgr.AccessQueue(queueName, MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING) '* open queue for output but not if MQM stopping
message = passedmqRequest
'* put the next message to the queue
mqMsg = New MQMessage()
mqMsg.WriteString(message)
mqMsg.Format = MQC.MQFMT_STRING
mqPutMsgOpts = New MQPutMessageOptions()
mqMsg.ReplyToQueueName = Response_queue
mqMsg.ReplyToQueueManagerName = Response_queue_mgt
Try
mqQueue.Put(mqMsg, mqPutMsgOpts)
responseQueue = mqQMgr.AccessQueue(mq_get_array(0), MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING)
Dim MQGetMessageOptions As New MQGetMessageOptions()
MQGetMessageOptions.Options = IBM.WMQ.MQC.MQGMO_WAIT + IBM.WMQ.MQC.MQGMO_FAIL_IF_QUIESCING + IBM.WMQ.MQC.MQGMO_CONVERT
MQGetMessageOptions.WaitInterval = 20000
MQGetMessageOptions.MatchOptions = MQC.MQMO_MATCH_MSG_ID
responseMSG = New MQMessage
responseMSG.MessageId = mqMsg.MessageId
Try
responseQueue.Get(responseMSG, MQGetMessageOptions)
Session_MqResponse = responseMSG.ReadString(responseMSG.DataLength)
Session_error_code = "0"
'
' at this point a response has been received and I should close
' the client channel connection
'
Catch mqe As MQException
'* report the error
Session_MqResponse = "MQQueue::get ended with " & mqe.Message & "<br/>"
mq_get_error = "Y"
Session_error_code = "1"
End Try
Catch mqe As MQException
'* report the error
Session_MqResponse = "MQQueue::Put ended with " & mqe.Message & "<br/>"
Session_error_code = "2"
End Try
Catch mqe As MQException
'* stop if failed
Session_MqResponse = "MQQueueManager::AccessQueue ended with error message = " & mqe.Message & "<br/>"
Session_MqResponse = Session_MqResponse & "create of MQQueueManager ended with error reason = " & mqe.Reason & "<br/>"
Session_error_code = "3"
End Try
Catch mqe As MQException
'* stop if failed
Session_MqResponse = "create of MQQueueManager ended with error message = " & mqe.Message & "<br/>"
Session_MqResponse = Session_MqResponse & "create of MQQueueManager ended with error reason = " & mqe.Reason & "<br/>"
Session_error_code = "4"
End Try
Upvotes: 0
Views: 331
Reputation: 2026
Walking through your code:
mqQMgr = New MQQueueManager(...)
This creates a MQQueueManager object, but also connects to the destination queue manager as a client connection - this will be the connections the network admin is talking about
mqQueue = mqQMgr.AccessQueue(queueName, MQC.MQOO_OUTPUT, ...)
This opens a queue on the destination queue manager for output
responseQueue = mqQMgr.AccessQueue(mq_get_array(0), MQC.MQOO_INPUT_SHARED, ...)
This opens a queue on the destination queue manager for input.
At this point you have 2 queues and one connection open on the destination queue manager. If you just drop into other code, then you are holding resources on the server. My understanding is that when the objects go out of scope, they would be destroyed, but I might be wrong for this language (out of practice!).
To explicitly free the resources you would need to just close the qmgr connection (as any queues it holds would be released) with appropriate error checking:
mqQMgr.Disconnect()
If you really want to explicitly clean up the queues and then the queue manager, you can do the following before the disconnect (with appropriate error checking):
mqQueue.Close()
responseQueue.Close()
Upvotes: 3
Reputation: 127
IBM says to close the queue when you're done with it.
So,
queueName.Close()
I hope this helps.
Upvotes: 0