8 Replies Latest reply on Sep 8, 2004 3:39 AM by adrian.brock

    How do I destroy a TemporaryQueue on the server?

    yurifyurif

      I create a temporary queue for each new client connecting to my "server" (a service running in JBoss). On the server side, I call
      TemporaryQueue q = qsession.createTemporaryQueue();
      and than pass the value of
      tempQueueTopic = q.getQueueName ();
      back to the client.

      The client than calls
      Queue queue = qsession.createQueue (tempQueueTopic);
      to connect to the same queue.

      The question is how/when does this temp queue get destroyed? Specifically, let's consider using JMS over HTTP (using HTTPServerILServlet). Suppose a client has conencted to the temp queue above and then termined ungracefully (without closing the connection). What I'm seeing is that somehow the sevlet is holding on to this JMS connection such that if I attempt to call TemporaryQueue.delete() on the server (after closing all server-side senders/receivers for this queue) I get the following exception:

      org.jboss.mq.SpyJMSException: Cannot delete the TemporaryQueue; - nested throwable: (org.jboss.mq.SpyJMSException: Cannot delete the TemporaryDestination; - nested throwable: (javax.jms.JMSExcept
      ion: Cannot delete temporary queue, it is in use.))
      at org.jboss.mq.SpyTemporaryQueue.delete(SpyTemporaryQueue.java:73)
      ...
      Caused by: javax.jms.JMSException: Cannot delete temporary queue, it is in use.
      at org.jboss.mq.server.JMSDestinationManager.deleteTemporaryDestination(JMSDestinationManager.java:715)
      at org.jboss.mq.server.JMSServerInterceptorSupport.deleteTemporaryDestination(JMSServerInterceptorSupport.java:174)
      at org.jboss.mq.security.ServerSecurityInterceptor.deleteTemporaryDestination(ServerSecurityInterceptor.java:217)
      at org.jboss.mq.server.TracingInterceptor.deleteTemporaryDestination(TracingInterceptor.java:396)
      at org.jboss.mq.server.JMSServerInvoker.deleteTemporaryDestination(JMSServerInvoker.java:174)
      at org.jboss.mq.il.jvm.JVMServerIL.deleteTemporaryDestination(JVMServerIL.java:177)
      at org.jboss.mq.Connection.deleteTemporaryDestination(Connection.java:483)
      ... 52 more

      So, essentially what I'm asking is
      1. Should I call tempQueue.delete () at all, or simply close all senders/receivers and hope that some sort of reference counting mechanism will destroy the queue?
      2. With HTTP IL, will the proxy sender/receiver be closed automatically when the client just dies without closing the session explicitely?

      Thanks,
      Yuri


        • 1. Re: How do I destroy a TemporaryQueue on the server?
          darranl

          From the J2EE 1.3 API, this is the description of the 'createTemporaryQueue' method.

          Creates a TemporaryQueue object. Its lifetime will be that of the QueueConnection unless it is deleted earlier.

          • 2. Re: How do I destroy a TemporaryQueue on the server?
            yurifyurif

            I'm aware of that, but I don't see how this answers my questions. I was trying to show that _I am_ trying to delete this topic earlier then closing the queue connection, but getting an exception.

            • 3. Re: How do I destroy a TemporaryQueue on the server?

              You cannot delete a temporary destination while is has subscribers/listeners.

              • 4. Re: How do I destroy a TemporaryQueue on the server?
                darranl

                 

                I don't see how this answers my questions.


                Well one of your questions was: -

                Should I call tempQueue.delete () at all, or simply close all senders/receivers and hope that some sort of reference counting mechanism will destroy the queue?


                Partly you were asking if there is anything that will automatically delete the queue.

                Creates a TemporaryQueue object. Its lifetime will be that of the QueueConnection unless it is deleted earlier.


                The extract from the API tells you that the queue will be automatically deleted.

                So that is how it answers one of your questions.

                • 5. Re: How do I destroy a TemporaryQueue on the server?
                  yurifyurif

                  Darran, Adrian,
                  thank you for your responses. They do shed some more light on the issue,
                  however my main problem is still unresolved. Perhaps I didn't make myself clear, so let me try to do this one more time.

                  My design:
                  A single Jboss service, multiple remote clients. There is a 2-way communication between the service and each od the clients: client->server via RPC calls (using RMI Invoker), and server->client using JMS queue. I believe it's quite common to have such a design these days, right?
                  When a client initiates the connection, the service creates a new TemporaryQueue and returns the name of this queue.
                  Next, the client calls qsession.createQueue (..) with this same name.
                  This works just fine.
                  *** Please confirm that this a legitimate technique. ***

                  Now, the problem that I'm trying to solve is that of a session resource clean-up. Since the server side service never closes its JVM JMS connection (and even JMS session), the temporary queue will never be destroyed. This would cause memory leaks.
                  So, somehow the server has to destroy these temp queues. The only way of doing it cleanly is to call tempQueue.delete (), right?

                  However, there is a catch. If I call delete () before the remote client has closed his connection, I get an exception as you can see in my previous message. So, this delete () calls has to be synchronized with the client closing his connection. The question is - how do I do that?

                  The situation is even more complicated when using JMS over HTTP. In this case, it's the server side HTTP servlet that actually opens the JMS connection on behalf of the client. After poking around the Jboss JMS source code I haven't found any trace of session expiration mechanism in this servlet. (Should I file a bug for this separately?). In other words, if the client dies without explicitly closing the JMS connection, it seems that this connection on the server will never be closed, hence among other things the temp destination will remain locked forever.
                  *** Please confirm or deny this ***
                  Therefore, in this case, it's impossible to delete the temp queue calling delete method on it.

                  To summarize,
                  when using HTTP UIL, the temp queue remains locked forever if the client dies;
                  when using UIL2, the connection is closed if the client dies, but still one must somehow synchronize the invocation of the tmpQueue.delete method on the server with the client connection closing.

                  Please advise,
                  Yuri



                  • 6. Re: How do I destroy a TemporaryQueue on the server?

                    If the server side is not closing its connections you've got a memory leak straight away.

                    The session that creates the temporary queue must be the one that
                    creates the receiver otherwise it won't work.

                    • 7. Re: How do I destroy a TemporaryQueue on the server?
                      yurifyurif

                       

                      The session that creates the temporary queue must be the one that creates the receiver otherwise it won't work.

                      Well, how do you explain the fact that the design that I outlined below works for me?
                      What is the right way of achieving the functionality that I need, i.e.
                      - creating a new JMS queue for each new remote client
                      - cleaning it up when the client disconnects (gracefully or ungracefully)?


                      • 8. Re: How do I destroy a TemporaryQueue on the server?

                        Use a TemporaryQueue, naturally.

                        But only the client/session creating the temporary queue can receive from it/delete it.