Returning a Proxy from the server within Glacier2

janosjanos GermanyJanos VeresOrganization: feat.Me Networks, Inc.Project: An offline social interaction platform.Member
edited November 2016 in Help Center

Hello there,

I have a setup of an ObjectAdapter behind a ReplicaGroup within an IceGrid accessed via a Glacier2 Router.
The ObjectAdapter on the server is responsible for:

  • Permission Verification (subclassed PermissionVerifier)
  • Session Management (subclassed SessionManager)
  • Custom Session interface (subclassed Session)

Session creation works as fine, the manager returns an indirect session proxy (Glacier2.SessionPrxHelper.uncheckedCast(current.adapter.createIndirectProxy(objectPrx.ice_getIdentity()))) to the client and the client is able to call methods on its session interface. There are quite a few methods, therefore it was decided to put them into separate interfaces and upon request return a proxy to these via the session as follows:

interface ProductManager {
    ProductSet getProducts(string filter);
}

interface ClientSession extends Glacier2.Session {
    ProductManager* getProductManager();
}

The implementation of getProductManager() looks like this:

@Override
public ProductManagerPrx getProductManager(Current __current) {
        if(_productManagerPrx == null) {
            ObjectPrx obj = __current.adapter.addWithUUID(new ProductManagerI(this));
            _productManagerPrx = ProductManagerPrxHelper.uncheckedCast(__current.adapter.createDirectProxy(obj.ice_getIdentity()));
        }
        return _productManagerPrx;
}

Previously I tried createIndirectProxy(idt) as I wanted to break free from the ReplicaGroup, but it doesn't change the result.

The problem is: Once the client receives the proxy, it sees the published endpoints, but due to the Ice.Default.Router property it essentially ignores the proxy's endpoint information. Therefore the proxies returned from the server cannot be used on the client side. Client log indicates that the operation getProjects() never leaves the client, instead an addProxies call is made and returns "successfully" and then the application hangs never returning from the sync call. Because the server also registers an object adapter I have Ice.Default.CollocationOptimized set to 0. The client application never times out, nor have I received any ObjectNotExistsExceptions.

Server: Java
Client: C#
Ice v3.6.3
The connection is NOT a bi-directional.

What would be the solution to this behaviour, so that the client can call operations on the returned proxies?

The logs on show nothing the following entries:

Client log - getProjectManager():

Information: 0 : Protocol: sending asynchronous request
   message type = 0 (request)
   compression status = 0 (not compressed; do not compress response, if any)
   message size = 106
   request id = 16
   identity = session/b3483bc9-2388-4ed0-9f5b-696a74c2c561
   facet = 
   operation = getProjectManager
   mode = 0 (normal)
   context = Region/CITY
   encoding = 1.1
Information: 0 : Network: sent 106 of 106 bytes via tcp
   local address = 172.22.231.217:49522
   remote address = 172.28.226.17:8023
Information: 0 : Network: received 14 of 14 bytes via tcp
   local address = 172.22.231.217:49522
   remote address = 172.28.226.17:8023
Information: 0 : Network: received 88 of 88 bytes via tcp
   local address = 172.22.231.217:49522
   remote address = 172.28.226.17:8023
Information: 0 : Protocol: received reply 
   message type = 2 (reply)
   compression status = 0 (not compressed; do not compress response, if any)
   message size = 102
   request id = 16
   reply status = 0 (ok)
   encoding = 1.1

Client log - getProjects(string filter):

Information: 0 : The thread 0x101c has exited with code 259 (0x103).
The thread 0x2d7c has exited with code 259 (0x103).
Protocol: sending validate connection 
   message type = 3 (validate connection)
   compression status = 0 (not compressed; do not compress response, if any)
   message size = 14
Information: 0 : Network: sent 14 of 14 bytes via tcp
   local address = 172.22.231.217:49522
   remote address = 172.28.226.17:8023
Information: 0 : Protocol: sending asynchronous request
   message type = 0 (request)
   compression status = 0 (not compressed; do not compress response, if any)
   message size = 149
   request id = 17
   identity = Dev.Glacier2/router
   facet = 
   operation = addProxies
   mode = 2 (idempotent)
   context = Region/CITY
   encoding = 1.1
Information: 0 : Network: sent 149 of 149 bytes via tcp
   local address = 172.22.231.217:49522
   remote address = 172.28.226.17:8023
Information: 0 : Network: received 14 of 14 bytes via tcp
   local address = 172.22.231.217:49522
   remote address = 172.28.226.17:8023
Information: 0 : Network: received 12 of 12 bytes via tcp
   local address = 172.22.231.217:49522
   remote address = 172.28.226.17:8023
Information: 0 : Protocol: received reply 
   message type = 2 (reply)
   compression status = 0 (not compressed; do not compress response, if any)
   message size = 26
   request id = 17
   reply status = 0 (ok)
   encoding = 1.1

Glacier2 log - getProjectManager():

02.11.16 20:41:45:462   Trace   Network received 14 of 14 bytes via tcp local address = 172.28.226.17:48810 remote address = 172.28.226.17:10194
02.11.16 20:41:45:462   Trace   Protocol    received close connection  message type = 4 (close connection) compression status = 1 (not compressed; compress response, if any) message size = 14
02.11.16 20:41:45:462   Trace   Network closed tcp connection local address = 172.28.226.17:48810 remote address = 172.28.226.17:10194
02.11.16 20:42:08:543   Trace   Network received 14 of 14 bytes via tcp local address = 127.0.0.1:35856 remote address = 127.0.0.1:48809
02.11.16 20:42:08:543   Trace   Protocol    received close connection  message type = 4 (close connection) compression status = 1 (not compressed; compress response, if any) message size = 14
02.11.16 20:42:08:543   Trace   Network closed tcp connection local address = 127.0.0.1:35856 remote address = 127.0.0.1:48809
02.11.16 20:42:58:703   Trace   Protocol    sending close connection  message type = 4 (close connection) compression status = 1 (not compressed; compress response, if any) message size = 14
02.11.16 20:42:58:703   Trace   Network sent 14 of 14 bytes via tcp local address = 172.28.226.17:48806 remote address = 172.28.226.17:45380
02.11.16 20:42:58:704   Trace   Network closed tcp connection local address = 172.28.226.17:48806 remote address = 172.28.226.17:45380

Glacier2 log - getProjects(string filter):

02.11.16 20:48:10:700   Trace   Network received 14 of 14 bytes via tcp local address = 172.28.226.17:48977 remote address = 172.28.226.17:10194
02.11.16 20:48:10:700   Trace   Protocol    received close connection  message type = 4 (close connection) compression status = 1 (not compressed; compress response, if any) message size = 14
02.11.16 20:48:10:700   Trace   Network closed tcp connection local address = 172.28.226.17:48977 remote address = 172.28.226.17:10194
02.11.16 20:48:38:562   Trace   Network received 14 of 14 bytes via tcp local address = 127.0.0.1:35856 remote address = 127.0.0.1:48952
02.11.16 20:48:38:562   Trace   Protocol    received close connection  message type = 4 (close connection) compression status = 1 (not compressed; compress response, if any) message size = 14
02.11.16 20:48:38:562   Trace   Network closed tcp connection local address = 127.0.0.1:35856 remote address = 127.0.0.1:48952
02.11.16 20:48:55:702   Trace   Protocol    sending close connection  message type = 4 (close connection) compression status = 1 (not compressed; compress response, if any) message size = 14
02.11.16 20:48:55:702   Trace   Network sent 14 of 14 bytes via tcp local address = 172.28.226.17:48982 remote address = 172.28.226.17:45380
02.11.16 20:48:55:704   Trace   Network closed tcp connection local address = 172.28.226.17:48982 remote address = 172.28.226.17:45380

Server log - getProjectManager() attached.
Server log - getProjects(string filter) attached.

Thanks in advance!

Regards,
Janos

p.s. sorry for the amount of details

Tagged:

Best Answer

Answers

  • benoitbenoit Rennes, FranceBenoit FoucherOrganization: ZeroC, Inc.Project: IceAdministrators, ZeroC Staff ZeroC Staff

    Hi,

    Can you attach the debugger to the C# client and check the stack traces of each thread? You can post the thread dumps here and we can check them out.

    I don't see why the invocation hangs, Ice should sent if after the addProxies call or fail is something went wrong.

    Cheers,
    Benoit.

  • janosjanos GermanyJanos VeresOrganization: feat.Me Networks, Inc.Project: An offline social interaction platform.Member
    edited November 2016

    Hi,

    it seems to be hanging on this line: Ice.dll!IceInternal.AsyncResultI.wait() Line 457

    Please note, that in this case a call to the GeneralManagerPrx.getUsers() was triggered first so it deviates from the previously posted code only in name of the operation getUsers().

    >Debug.ListCallStack /AllThreads
    Callstack for Thread 7 (Thread Id: 9560 (0x2558)):
     Index  Function
    --------------------------------------------------------------------------------
     1      WindowsBase.dll!System.Windows.Threading.DispatcherSynchronizationContext.Wait(System.IntPtr[] waitHandles, bool waitAll, int millisecondsTimeout)
     2      [External Code]
    *3      Ice.dll!IceInternal.AsyncResultI.wait()
     4      MyClient-IceCommons.dll!MyClient.slicehub.provider.generals.GeneralPrxHelper.end_getUsers(Ice.AsyncResult r__ = {IceInternal.TwowayOutgoingAsync<MyClient.slicehub.provider.generals.Callback_General_getUsers>})
     5      MyClient-IceCommons.dll!MyClient.slicehub.provider.generals.GeneralPrxHelper.getUsers(System.Collections.Generic.Dictionary<string,string> context__ = null, bool explicitCtx__ = false)
     6      MyClient-IceCommons.dll!MyClient.slicehub.provider.generals.GeneralPrxHelper.getUsers()
     7      MyClient.dll!MyClient.ViewLayer.Bindings.AppStatusBarViewModel.AppStatusBarViewModel()
     8      MyClient.dll!MyClient.ViewLayer.Forms.IceMenu.IceMenu()
     9      MyClient.dll!MyClient.ViewLayer.Forms.LogonWindow.OpenAppropriateStartingWindow()
     10     MyClient.dll!MyClient.ViewLayer.Forms.LogonWindow.LogInUserToService(string username = "EU\\veres")
     11     [Resuming Async Method]
     12     mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
     13     mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
     14     mscorlib.dll!System.Runtime.CompilerServices.AsyncMethodBuilderCore.MoveNextRunner.Run()
     15     WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)
     16     WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler = null)
     17     WindowsBase.dll!System.Windows.Threading.DispatcherOperation.InvokeImpl()
     18     mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
     19     mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
     20     mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
     21     WindowsBase.dll!MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
     22     WindowsBase.dll!System.Windows.Threading.DispatcherOperation.Invoke()
     23     WindowsBase.dll!System.Windows.Threading.Dispatcher.ProcessQueue()
     24     WindowsBase.dll!System.Windows.Threading.Dispatcher.WndProcHook(System.IntPtr hwnd, int msg, System.IntPtr wParam, System.IntPtr lParam, ref bool handled)
     25     WindowsBase.dll!MS.Win32.HwndWrapper.WndProc(System.IntPtr hwnd = 1247474, int msg, System.IntPtr wParam = 0, System.IntPtr lParam = 0, ref bool handled = false)
     26     WindowsBase.dll!MS.Win32.HwndSubclass.DispatcherCallbackOperation(object o)
     27     WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate callback, object args, int numArgs)
     28     WindowsBase.dll!System.Windows.Threading.ExceptionWrapper.TryCatchWhen(object source = {System.Windows.Threading.Dispatcher}, System.Delegate callback, object args, int numArgs, System.Delegate catchHandler = null)
     29     WindowsBase.dll!System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority priority, System.TimeSpan timeout, System.Delegate method, object args, int numArgs)
     30     WindowsBase.dll!MS.Win32.HwndSubclass.SubclassWndProc(System.IntPtr hwnd = 1247474, int msg, System.IntPtr wParam = 0, System.IntPtr lParam = 0)
     31     [External Code]
     32     WindowsBase.dll!System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame frame = {System.Windows.Threading.DispatcherFrame})
     33     PresentationFramework.dll!System.Windows.Application.RunDispatcher(object ignore)
     34     PresentationFramework.dll!System.Windows.Application.RunInternal(System.Windows.Window window)
     35     MyClient Dev.exe!MyClient_Dev.App.Main()
     36     [External Code]
     37     mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args)
     38     Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
     39     mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
     40     mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx)
     41     mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state)
     42     mscorlib.dll!System.Threading.ThreadHelper.ThreadStart()
    

    I tried a different approach, only returning the string identity from the server and then constructing the proxy on the client side. Unfortunately it didn't change the result.

    Kind regards,
    Janos

  • janosjanos GermanyJanos VeresOrganization: feat.Me Networks, Inc.Project: An offline social interaction platform.Member

    Hi,

    as it turns out, I was too quick on the client side. If the createManager() operation is called from within the Glacier2.SessionCallback.connected() event, the ICE runtime hangs on waiting for a response. Once I wrapped the very first method in a Task.Run(() => createManagers()) the returned proxies seem to function normally.

    Is this standard behaviour? Do I have to wrap my custom event incovator IceConnected in any way before dispatching it through the client?

    Regards,
    Janos

  • benoitbenoit Rennes, FranceBenoit FoucherOrganization: ZeroC, Inc.Project: IceAdministrators, ZeroC Staff ZeroC Staff
    Accepted Answer

    Hi,

    Can you provide a little more information on your client? Are you using an Ice::Dispatcher for instance? It looks like the synchronous calls form the main thread are hanging, possibly because you use a dispatcher.

    See https://doc.zeroc.com/display/Ice36/Dispatching+Invocations+to+User+Threads#DispatchingInvocationstoUserThreads-DispatcherImplementationNotes

    You should never make synchronous invocations from the dispatcher thread (the main thread here). You should instead using asynchronous invocations (such as begin_getUsers()).

    Cheers,
    Benoit.

  • janosjanos GermanyJanos VeresOrganization: feat.Me Networks, Inc.Project: An offline social interaction platform.Member

    Hi,

    Yes, I do have a dispatcher. Based on the WPF example, Implemented as the following:

                id.properties.setProperty("Ice.ImplicitContext", "Shared");
                id.dispatcher = (action, connection) =>
                {
                    Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, action);
                };
    

    In most of the cases I had begin_op, with a few exceptions. I failed to have the sync calls wrapped around with non-UI different thread. This makes altogether sense, I simply forgot about the invocation being executed on the UI thread. Thanks! :)

    I had a different issue with the setup today, as I changed one parameter of the slice class to optional(1), and suddenly the Server was throwing NoObjectFactory exceptions. But that's a different topic, I'll have to investigate that separately.

    Regards,
    Janos

Sign In or Register to comment.