Archived
Returning a Proxy from the server within Glacier2
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 ObjectNotExistsException
s.
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
Comments
-
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.0 -
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 operationgetUsers()
.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,
Janos0 -
Hi,
as it turns out, I was too quick on the client side. If the
createManager()
operation is called from within theGlacier2.SessionCallback.connected()
event, the ICE runtime hangs on waiting for a response. Once I wrapped the very first method in aTask.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,
Janos0 -
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.
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.0 -
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,
Janos0