Jonathan Small
Jonathan Small

Reputation: 1079

Visual Basic web API uses mq series messaging but never releases the connection

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

Answers (2)

JasonE
JasonE

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

NothingToSeeHere
NothingToSeeHere

Reputation: 127

IBM says to close the queue when you're done with it.

So,

queueName.Close()

Accessing Queues and Topics

I hope this helps.

Upvotes: 0

Related Questions