Problem: When doing client/server-programming, the client calls a function on the server -- EJB, RMI, Web-Services, etc., in a language such as Java. Sometimes, the connection to the server gets lost, as the server is restarted, redeployed, network was down and up again, etc. Then, the client's call to the server fails; after reconnecting, it should be possible to repeat the call and get the wanted result. Possibly, the reconnection will take some time, if the network has a longer "outing". How can we ensure that the call is done in any case, even if there are transient network/deployment problems? Solution 1: The client's Business Delegate (you have one, haven't you?) calls a "ping()" or another such method before calling the real business method on the server. If the connection is broken, catch the exception, try to reconnect, until such a ping goes through. Disadvantages:
- doubles the number of c/s calls
- if the ping succeeds, but the real call fails due to problems in this nano second, you're out of luck
protected IServer mServer; public ResultObject businessMethod(final int intParam, final String stringParam) throws BusinessException { class BusinessMethodRunnable implements Runnable() { private ResultObject result; public void run() { // do the server call itself, and store the result. result = mServer.businessMethod(intParam, stringParam); } public ResultObject getResultObject() { return resultObject; } } BusinessMethodRunnable runnable = new BusinessMethodRunnable(); // wraps the call, to ensure successful completion callMethod(runnable); return runnable.getResultObject(); } protected void callMethod(Runnable runnable) throws BusinessException { // repeat, until the loop is left with return after a successful call while (true) { try { if (mServer==null) // should block until the connection has been established connectToServer(); // do the real call here. runnable.run(); return; } // a business exception needs to be passed to the calling code catch (BusinessException e) { throw e; } // a runtime exception also needs to be passed to the calling code ... catch (RuntimeExceptione ) { throw e; // alternatively: // throw new BusinessException("RuntimeException caught", e); } catch (Exception e) { logException(e); // connection down, no resources to be freed(?) mServer = null; } } }
No comments:
Post a Comment