Archived

This forum has been archived. Please start a new discussion on GitHub.

Destroying Proxy during operation in another thread.

Hi,

We have multiple clients, and 1 front-end server, and several backend servers.

The front-end server and backend servers interact with Icegrid session (resource allocations).
clients and the front-end server uses our own communication mechanism (not Ice).

1 client connection to the frond-end server will allocate one backend server, and need to call RPC function first(), second() and third() sequentially.

The front-end server will have 1 thread per client connection.

The front-end server has 1 Ice communicator objects, and get the Proxy object to communicate with backend server.

Let's assume that client is connected to the front-end server, and front-end server created a Proxy object to communicate to one of its backend server. And front-end passed this Proxy object to the assigned thread, and that thread will call proxy->first(), proxy->second(), and so on.

During proxy->second() call, the connection between the client and the front-end is disconnected, and the frontend wants to release all the resources of that connection.

If the front-end creates multiple Communicator objects per connection, I would call Communicator::destroy() or shutdown(), so that the serving thread will get Ice::CommunicatorDestroyedException, and serving thread can terminate gracefully.

However, I cannot destroy the communicator, since it is used by other clients/threads.

Is there any method so that I can remove the relationship of particular proxy from the communicator?

thanks,

Comments

  • benoit
    benoit Rennes, France
    Hi,

    No, it's not possible to break this relationship. The easiest is to check for a "destroy" flag in the thread and exit the thread when this flag gets set. You could check this flag before performing each remote call.

    If you don't wait to wait for the response of each call before exiting the thread, you could also use AMI as well in order to not wait for the response. For example, something along those lines should do the job:
    // C++
    class MyThread : public IceUtil::Thread, IceUtil::Monitor<IceUtil::Mutex>
    {
       class DestroyedException {
       };
    
    public:
    
        MyThread() : _destroyed(false) {
        }
    
        virtual void 
        run() {
            Ice::CallbackPtr completedCB = Ice::newCallback(this, &MyThread::completed);
            Ice::AsyncResultPtr result;
            try {
                // Call 1
                result = waitForResponseOrDestroyed(proxy->begin_call1(completedCB));
                proxy->end_call1(result);
            
                // Call 2
                result = waitForResponseOrDestroyed(proxy->begin_call2(completedCB));
                proxy->end_call2(result);
             } catch(const DestroyedException& ex) {
                // Graceful termination.
             }
        }
    
        void
        destroy() {
            Lock sync(*this);
            _destroyed = true;
            notify();
        }
    
    private:
    
        void 
        completed(const Ice::AsyncResultPtr&) {
            Lock sync(*this);
            notify();
        }
    
        Ice::AsyncResultPtr
        waitForResponseOrDestroyed(const Ice::AsyncResultPtr& result) {
            Lock sync(*this);
            while(!_destroyed && !result->isCompleted()) {
                wait();
            }
            if(_destroyed) {
                throw DestroyedException();
            }
            return result;
        }
    
        bool _destroyed;
    };
    

    Let us know if you need more information on this!

    Cheers,
    Benoit.