Very true, well said. -----Original Message----- From: Gregg Wonderly [mailto:[email protected]] Sent: Thursday, June 14, 2012 9:37 AM To: [email protected] Subject: Re: Client timeouts and remote calls
If you use a smart proxy, and put the lease renewal call inside the smart proxy, and register a listener, you can see the renewal fail. But, you still have to know what that means based on how the service and the lease interact. To get a legitimate, two way, liveness test, you really have to have a conversation with the server, from the client, and have a view of the endpoint activities on the server. There are lots of ways to engineer this, and both leasing or transactions can be part of the solution. But, in the end, you must decide what you need to know, and then think through what you are expecting vs what is actually achievable using the facilities you can deploy. Most of the time, the true test, is merely to be able to use the endpoint(s) end to end by making a call from the client to the service for that liveness test. Given all the possible forms of partial failure that can occur in a distributed system. You can't rely on detached functionality, such as leases, as the "only" way to know that something is working on the other end. Gregg Wonderly On Jun 14, 2012, at 7:37 AM, Christopher Dolan wrote: > Very true about the possible client/server asymmetry of leases. However, I've > found that in most cases, the server that hosts the lease manager is the same > one that hosts the events. So if it crashes and the client tries to renew the > lease, you find out via the lease renewal failure. > > Chris > > -----Original Message----- > From: Greg Trasuk [mailto:[email protected]] > Sent: Thursday, June 14, 2012 3:21 AM > To: [email protected] > Subject: RE: Client timeouts and remote calls > > > Look carefully at what Gregg said: >> ...If you turn on DGC, or use a Lease on the client received endpoint, > then you might be able to know that a client is actually gone, rather > than just temporarily unreachable. > > And then look at what Chris said: >> ...Then the client also knows if the server dies and can re-subscribe. > > See the difference? Gregg is talking about the server knowing the > client is gone, and Chris is talking about the client knowing the server > is gone. > > A common misconception about Jini Leases is that they let the client > know when the service dies. Not true, unfortunately. Leases are there > so that the _Service_ can clean up any state that's held on behalf of > the client, when the client fails to renew the lease. > > The fact that you can renew a lease in no way guarantees that the > service is working. The service could very well have handed off the > lease to some other landlord implementation. Even if the lease is > handled by the service itself, it's not necessarily linked to the actual > event delivery (or whatever). In any case, the lease duration is > probably much longer than the time boundary you'd like to have on > detecting a failure. > > Unfortunately, the only way the client knows if event delivery has > failed is if events stop showing up. In the case of a server that is > just holding data for you (like a lease on a transaction or a JavaSpace > entry), you only know the server has failed when you go to call it and > can't reach it. Leases tell you nothing from the client end. Look at > it this way: Your apartment might be leased for another six months, but > that doesn't rule out the possibility that it burns down. > > Other than that, I really like Chris's argument for a three-thread > executor for event delivery. > > Cheers, > > Greg. > > On Wed, 2012-06-13 at 22:31, Christopher Dolan wrote: >> I agree about using a Lease. Then the client also knows if the server dies >> and can re-subscribe. >> >> If the latency of the timeout is a concern, then my solution has been to use >> a 3 thread executor to send the updates. I chose 3 as a good number because >> of the philosophy of "once is an event, twice is a coincidence and thrice is >> conspiracy." That is, with 1 thread you should expect to be blocked; with 2 >> threads you should rarely be blocked but you could be blocked by bad luck; >> with 3 threads you'll only be blocked if there's a noteworthy outage which >> probably has a cause outside of your control so more threads won't help. >> >> Chris >> >> ________________________________________ >> From: Gregg Wonderly [[email protected]] >> Sent: Wednesday, June 13, 2012 3:53 PM >> To: [email protected] >> Subject: Re: Client timeouts and remote calls >> >> There are timeouts that you can change in your Configuration to control how >> long the waits occur. If it's important that everyone agree on the values >> being changed, you could include the use of a transaction so that if one >> client dies in the middle, then everyone can revert, and you can retry to >> get things to a sane state. >> >> This is important if the data the clients receives, controls how they >> interact with the service. But, you can otherwise, just do what you are >> doing, without a transaction. If you turn on DGC, or use a Lease on the >> client received endpoint, then you might be able to know that a client is >> actually gone, rather than just temporarily unreachable. >> >> Gregg >> >> On Jun 13, 2012, at 2:13 PM, Sergio Aguilera Cazorla wrote: >> >>> Hello, >>> >>> I have a question regarding client-side timeouts in Jini / Apache River. I >>> am finishing a program where a certain number of clients can obtain a proxy >>> and set / get properties (values) from an exported class in a server. Each >>> client becomes a RemoteEventListener of the server, so each time a property >>> is changed, the server calls notify() in ALL clients to make them aware >>> that a property has changed (and all clients update their data). >>> >>> This architecture performs great if client programs finish in a "graceful" >>> way, because I have a register / unregister mechanism that makes the server >>> have an updated list of "alive" clients. However, if client machines "die >>> suddenly", the server will be unaware and will try to call notify() next >>> time that call is needed. Example (setSomething is a remote method on the >>> Server): >>> >>> public void setSomething(String param) { >>> >>> <do the Stuff> >>> Remote event ev = <proper RemoteEvent object> >>> for(RemoteEventListener l : listeners) { >>> >>> try { >>> >>> l.notify(ev); >>> >>> } catch(Exception e) { listeners.remove(l); } >>> >>> } >>> >>> } >>> >>> I'm sure you see where I want to go: if some clients in the list died >>> suddenly, the notify() will be called over them. A ConnectException is >>> thrown and the client is removed properly but... it takes a long time for >>> the exception to be thrown! Do you know how to control this situation? >>> >>> Thanks in advance! >>> >>> ADDITIONAL DATA: >>> I have tried setting un the following RMI System properies, and didn't work: >>> System.setProperty("sun.rmi.transport.tcp.responseTimeout","2000"); >>> System.setProperty("sun.rmi.transport.tcp.handshakeTimeout","2000"); >>> System.setProperty("sun.rmi.transport.tcp.readTimeout","2000"); >>> System.setProperty("sun.rmi.transport.connectionTimeout","2000"); >>> System.setProperty("sun.rmi.transport.proxy.connectTimeout ","2000"); >>> >>> At present moment, under Windows XP for both client and server, the >>> ConnectException takes exactly* 21 seconds* to be thrown. Do you know the >>> reason for this value? >>> >>> -- >>> *Sergio Aguilera* >> >
