requestcorrelator.java
来自「JGRoups源码」· Java 代码 · 共 923 行 · 第 1/3 页
JAVA
923 行
* Called by the protocol below when a message has been received. The * algorithm should test whether the message is destined for us and, * if not, pass it up to the next layer. Otherwise, it should remove * the header and check whether the message is a request or response. * In the first case, the message will be delivered to the request * handler registered (calling its <code>handle()</code> method), in the * second case, the corresponding response collector is looked up and * the message delivered. */ public void receive(Event evt) { switch(evt.getType()) { case Event.SUSPECT: // don't wait for responses from faulty members receiveSuspect((Address)evt.getArg()); break; case Event.VIEW_CHANGE: // adjust number of responses to wait for receiveView((View)evt.getArg()); break; case Event.SET_LOCAL_ADDRESS: setLocalAddress((Address)evt.getArg()); break; case Event.MSG: if(!receiveMessage((Message)evt.getArg())) return; break; } if(transport instanceof Protocol) ((Protocol)transport).passUp(evt); else if(log.isErrorEnabled()) log.error("we do not pass up messages via Transport"); } /** */ public final void start() { if(deadlock_detection) { startScheduler(); } started=true; } public void stop() { stopScheduler(); started=false; } void startScheduler() { if(scheduler == null) { scheduler=new Scheduler(); if(deadlock_detection && call_stack_setter == null) { call_stack_setter=new CallStackSetter(); scheduler.setListener(call_stack_setter); } if(concurrent_processing) scheduler.setConcurrentProcessing(concurrent_processing); scheduler.start(); } } void stopScheduler() { if(scheduler != null) { scheduler.stop(); scheduler=null; } } // ....................................................................... /** * <tt>Event.SUSPECT</tt> event received from a layer below. * <p> * All response collectors currently registered will * be notified that <code>mbr</code> may have crashed, so they won't * wait for its response. */ public void receiveSuspect(Address mbr) { RequestEntry entry; // ArrayList copy; if(mbr == null) return; if(log.isDebugEnabled()) log.debug("suspect=" + mbr); // copy so we don't run into bug #761804 - Bela June 27 2003 // copy=new ArrayList(requests.values()); // removed because ConcurrentReaderHashMap can tolerate concurrent mods (bela May 8 2006) for(Iterator it=requests.values().iterator(); it.hasNext();) { entry=(RequestEntry)it.next(); if(entry.coll != null) entry.coll.suspect(mbr); } } /** * <tt>Event.VIEW_CHANGE</tt> event received from a layer below. * <p> * Mark all responses from members that are not in new_view as * NOT_RECEIVED. * */ public void receiveView(View new_view) { RequestEntry entry; // ArrayList copy; // copy so we don't run into bug #761804 - Bela June 27 2003 // copy=new ArrayList(requests.values()); // removed because ConcurrentReaderHashMap can tolerate concurrent mods (bela May 8 2006) for(Iterator it=requests.values().iterator(); it.hasNext();) { entry=(RequestEntry)it.next(); if(entry.coll != null) entry.coll.viewChange(new_view); } } /** * Handles a message coming from a layer below * * @return true if the event should be forwarded further up, otherwise false (message was consumed) */ public boolean receiveMessage(Message msg) { Object tmpHdr; // i. If header is not an instance of request correlator header, ignore // // ii. Check whether the message was sent by a request correlator with // the same name (there may be multiple request correlators in the same // protocol stack...) tmpHdr=msg.getHeader(name); if(tmpHdr == null || !(tmpHdr instanceof Header)) { return true; } Header hdr=(Header)tmpHdr; if(hdr.corrName == null || !hdr.corrName.equals(name)) { if(log.isTraceEnabled()) { log.trace(new StringBuffer("name of request correlator header (").append(hdr.corrName). append(") is different from ours (").append(name).append("). Msg not accepted, passed up")); } return true; } // If the header contains a destination list, and we are not part of it, then we discard the // request (was addressed to other members) java.util.List dests=hdr.dest_mbrs; if(dests != null && local_addr != null && !dests.contains(local_addr)) { if(log.isTraceEnabled()) { log.trace(new StringBuffer("discarded request from ").append(msg.getSrc()). append(" as we are not part of destination list (local_addr="). append(local_addr).append(", hdr=").append(hdr).append(')')); } return false; } // [Header.REQ]: // i. If there is no request handler, discard // ii. Check whether priority: if synchronous and call stack contains // address that equals local address -> add priority request. Else // add normal request. // // [Header.RSP]: // Remove the msg request correlator header and notify the associated // <tt>RspCollector</tt> that a reply has been received switch(hdr.type) { case Header.REQ: if(request_handler == null) { if(log.isWarnEnabled()) { log.warn("there is no request handler installed to deliver request !"); } return false; } if(deadlock_detection) { if(scheduler == null) { log.error("deadlock_detection is true, but scheduler is null: this is not supposed to happen" + " (discarding request)"); break; } Request req=new Request(msg); java.util.Stack stack=hdr.callStack; if(hdr.rsp_expected && stack != null && local_addr != null) { if(stack.contains(local_addr)) { if(log.isTraceEnabled()) log.trace("call stack=" + hdr.callStack + " contains " + local_addr + ": adding request to priority queue"); scheduler.addPrio(req); break; } } scheduler.add(req); break; } handleRequest(msg); break; case Header.RSP: msg.removeHeader(name); RspCollector coll=findEntry(hdr.id); if(coll != null) { Address sender=msg.getSrc(); Object retval=null; byte[] buf=msg.getBuffer(); try { retval=marshaller != null? marshaller.objectFromByteBuffer(buf) : Util.objectFromByteBuffer(buf); } catch(Exception e) { log.error("failed unmarshalling buffer into return value", e); try { retval=marshaller != null? marshaller.objectToByteBuffer(e) : Util.objectToByteBuffer(e); } catch(Exception e1) { log.error("failed marshalling exception " + e1 + " into buffer", e1); } } coll.receiveResponse(retval, sender); } break; default: msg.removeHeader(name); if(log.isErrorEnabled()) log.error("header's type is neither REQ nor RSP !"); break; } return false; } public Address getLocalAddress() { return local_addr; } public void setLocalAddress(Address local_addr) { this.local_addr=local_addr; } // ....................................................................... /** * Add an association of:<br> * ID -> <tt>RspCollector</tt> */ private void addEntry(long id, RequestEntry entry) { Long id_obj = new Long(id); synchronized(requests) { if(!requests.containsKey(id_obj)) requests.put(id_obj, entry); else if(log.isWarnEnabled()) log.warn("entry " + entry + " for request-id=" + id + " already present !"); } } /** * Remove the request entry associated with the given ID * * @param id the id of the <tt>RequestEntry</tt> to remove */ private void removeEntry(long id) { Long id_obj = new Long(id); // changed by bela Feb 28 2003 (bug fix for 690606) // changed back to use synchronization by bela June 27 2003 (bug fix for #761804), // we can do this because we now copy for iteration (viewChange() and suspect()) requests.remove(id_obj); } /** * @param id the ID of the corresponding <tt>RspCollector</tt> * * @return the <tt>RspCollector</tt> associated with the given ID */ private RspCollector findEntry(long id) { Long id_obj = new Long(id); RequestEntry entry; entry=(RequestEntry)requests.get(id_obj); return((entry != null)? entry.coll:null); } /** * Handle a request msg for this correlator * * @param req the request msg */ private void handleRequest(Message req) { Object retval; byte[] rsp_buf; Header hdr, rsp_hdr; Message rsp; // i. Remove the request correlator header from the msg and pass it to // the registered handler // // ii. If a reply is expected, pack the return value from the request // handler to a reply msg and send it back. The reply msg has the same // ID as the request and the name of the sender request correlator hdr=(Header)req.removeHeader(name);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?