Archived

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

Exception routing with Glacier

Hi,

i did change the glacier2/callback demo to make the server invoke the
callback continuously.
In the case the client terminates, i get a dispatch waring in glacier:
c:/Ice-3.0.0/bin/glacier2router.exe: warning: dispatch exception: .\ConnectionI.cpp:2030: Ice::CloseConnectionException:
protocol error: connection closed
identity: t+*,AptZ?#\'k\/$u*BIo!/callbackReceiver
facet:
operation: callback

and a Ice.UnknownLocalException:
Ice.UnknownLocalException: UnknownLocalException
    unknown = ".\ConnectionI.cpp:2030: Ice::CloseConnectionException:
protocol error: connection closed"
   at Ice.ObjectPrxHelperBase.rethrowException__(LocalException ex) in C:\projects\ICE.SOURCES\IceCS-3.0.0-dotnetfx2.0\src\Ice\Proxy.cs:line 687
   at Demo.CallbackReceiverPrxHelper.callback(Context context__) in C:\Ice-3.0.0\democs\Glacier2\callback\generated\Callback.cs:line 97
   at CallbackI.EndLessUpdates(Object state) in C:\Ice-3.0.0\democs\Glacier2\callback\CallbackI.cs:line 31

it would be nicer to get the Ice::CloseConnectionException on server side.
otherwise the server must parse the 'unknown' field to find out about the
exception.

This could be neccessary to make decissions like remove the callback from an internal update list (e.g. in case of ObjectNotExitx) or keep the callback and retrying later (e.g. in case of TimeOut or other network exceptions) ...

this is the changed server code: (CallbackI.cs)
using Demo;
using System;

public sealed class CallbackI : CallbackDisp_
{
    public override void initiateCallback(CallbackReceiverPrx proxy, Ice.Current current)
    {
        Console.WriteLine("initiating callback");

        System.Threading.ThreadPool.QueueUserWorkItem( EndLessUpdates, new object[] { proxy, current.ctx } );
    }

    private void EndLessUpdates( object state )
    {
        object[] os = state as object[];
        CallbackReceiverPrx proxy = os[0] as CallbackReceiverPrx;
        Ice.Context ctx = os[1] as Ice.Context;
        while( true )
        {
            try
            {
                proxy.callback( ctx );
            }
            catch( System.Exception ex )
            {
                Console.Error.WriteLine( ex );
            }
            System.Threading.Thread.Sleep( 100 );
        }
    }

    public override void shutdown(Ice.Current current)
    {
        Console.WriteLine("Shutting down...");
	try
	{
	    current.adapter.getCommunicator().shutdown();
	}
	catch(System.Exception ex)
	{
	    Console.Error.WriteLine(ex);
	}
    }
}

Comments

  • DeepDiver wrote:
    it would be nicer to get the Ice::CloseConnectionException on server side.
    otherwise the server must parse the 'unknown' field to find out about the
    exception.

    I'm afraid this is not possible. CloseConnectionException is a local exception, so it cannot be transmitted over the wire. It does not have any meaning outside the process where it is raised.
    DeepDiver wrote:
    This could be neccessary to make decissions like remove the callback from an internal update list (e.g. in case of ObjectNotExitx) or keep the callback and retrying later (e.g. in case of TimeOut or other network exceptions)

    You shouldn't do this by analyzing the exception, but with Glacier2's session management. When the client dies, Glacier2 destroys the session. You can then take action in your session object. For more details, have a look at the article "Session Management with Glacier2" in issue 1 of Connections.

    Also note that it is not a good idea to make any decisions in your code based on whether you receive a CloseConnectionException, except for debugging purposes. You get a CloseConnectionException only if your client has a chance to send a TCP/IP FIN message. If a computer crashes, or the network connections is terminated for some other reason, then you won't get a CloseConnectionException, but only a TimeoutException.
  • Thanks alot for your answer, Marc.

    I was expecting no difference in exception handling weather a glaicer router is
    in between or not.

    Because only the ui client is communicating with the servers via glacier and
    the servers talk to each other directly, I remove callbacks on exception basis.

    Regards,

    Tom