@ManagedOperation( description = "Sends a STABLE message to all senders. This causes message purging and potential" + " retransmissions from senders") public void sendStableMessages() { for (Map.Entry<Address, ReceiverEntry> entry : recv_table.entrySet()) { Address dest = entry.getKey(); ReceiverEntry val = entry.getValue(); NakReceiverWindow win = val != null ? val.received_msgs : null; if (win != null) { long[] tmp = win.getDigest(); long low = tmp[0], high = tmp[1]; if (val.last_highest == high) { if (val.num_stable_msgs >= val.max_stable_msgs) { continue; } else val.num_stable_msgs++; } else { val.last_highest = high; val.num_stable_msgs = 1; } sendStableMessage(dest, val.recv_conn_id, low, high); } } }
@ManagedOperation(description = "Compacts the retransmission tables") public void compact() { for (Map.Entry<Address, ReceiverEntry> entry : recv_table.entrySet()) { NakReceiverWindow win = entry.getValue().received_msgs; win.compact(); } }
public static void testDetermineMergeParticipantsAndMergeCoords4() { Address a = Util.createRandomAddress(), b = Util.createRandomAddress(), c = Util.createRandomAddress(), d = Util.createRandomAddress(); org.jgroups.util.UUID.add(a, "A"); org.jgroups.util.UUID.add(b, "B"); org.jgroups.util.UUID.add(c, "C"); org.jgroups.util.UUID.add(d, "D"); View v1 = View.create(a, 1, a, b); View v2 = View.create(c, 1, c, d); Map<Address, View> map = new HashMap<>(); map.put(a, v1); map.put(b, v1); map.put(d, v2); StringBuilder sb = new StringBuilder("map:\n"); for (Map.Entry<Address, View> entry : map.entrySet()) sb.append(entry.getKey() + ": " + entry.getValue() + "\n"); System.out.println(sb); Collection<Address> merge_participants = Util.determineMergeParticipants(map); System.out.println("merge_participants = " + merge_participants); assert merge_participants.size() == 3; assert merge_participants.contains(a) && merge_participants.contains(c) && merge_participants.contains(d); Collection<Address> merge_coords = Util.determineMergeCoords(map); System.out.println("merge_coords = " + merge_coords); assert merge_coords.size() == 2; assert merge_coords.contains(a) && merge_coords.contains(c); }
@ManagedOperation( description = "Purges highes delivered messages and compacts the retransmission tables") public void purgeAndCompact() { for (Map.Entry<Address, ReceiverEntry> entry : recv_table.entrySet()) { NakReceiverWindow win = entry.getValue().received_msgs; win.stable(win.getHighestDelivered()); win.compact(); } }
@ManagedOperation(description = "Prints the contents of the send windows for all members") public String printSendWindowMessages() { StringBuilder ret = new StringBuilder(local_addr + ":\n"); for (Map.Entry<Address, SenderEntry> entry : send_table.entrySet()) { Address addr = entry.getKey(); Table<Message> buf = entry.getValue().sent_msgs; ret.append(addr).append(": ").append(buf.toString()).append('\n'); } return ret.toString(); }
/** * Removed rejected merge requests from merge_rsps and coords. This method has a lock on * merge_rsps */ private void removeRejectedMergeRequests(Collection<Address> coords) { for (Map.Entry<Address, MergeData> entry : merge_rsps.getResults().entrySet()) { Address member = entry.getKey(); MergeData data = entry.getValue(); if (data.merge_rejected) { if (data.getSender() != null) coords.remove(data.getSender()); merge_rsps.remove(member); } } }
public void run() { for (Map.Entry<Address, ReceiverEntry> entry : recv_table.entrySet()) { Address target = entry.getKey(); // target to send retransmit requests to ReceiverEntry val = entry.getValue(); Table<Message> buf = val != null ? val.received_msgs : null; if (buf != null && buf.getNumMissing() > 0) { SeqnoList missing = buf.getMissing(); if (missing != null) retransmit(missing, target); } } }
@ManagedOperation(description = "Returns the sizes of all NakReceiverWindow.RetransmitTables") public String printRetransmitTableSizes() { StringBuilder sb = new StringBuilder(); for (Map.Entry<Address, ReceiverEntry> entry : recv_table.entrySet()) { NakReceiverWindow win = entry.getValue().received_msgs; sb.append(entry.getKey() + ": ") .append(win.getRetransmitTableSize()) .append(" (capacity=" + win.getRetransmitTableCapacity()) .append(", fill factor=" + win.getRetransmitTableFillFactor() + "%)\n"); } return sb.toString(); }
@ManagedOperation public void suspect(String suspected_member) { if (suspected_member == null) return; Map<Address, String> contents = UUID.getContents(); for (Map.Entry<Address, String> entry : contents.entrySet()) { String logical_name = entry.getValue(); if (logical_name != null && logical_name.equals(suspected_member)) { Address suspect = entry.getKey(); if (suspect != null) up(new Event(Event.SUSPECT, suspect)); } } }
String dumpMessages(HashMap map) { StringBuffer sb = new StringBuffer(); Map.Entry entry; List l; if (map != null) { synchronized (map) { for (Iterator it = map.entrySet().iterator(); it.hasNext(); ) { entry = (Map.Entry) it.next(); l = (List) entry.getValue(); sb.append(entry.getKey()).append(": "); sb.append(l.size()).append(" msgs\n"); } } } return sb.toString(); }
void bundleAndSend() { Map.Entry entry; IpAddress dest; ObjectOutputStream out; InetAddress addr; int port; byte[] data; List l; if (Trace.trace) { Trace.info( "UDP.BundlingOutgoingPacketHandler.bundleAndSend()", "\nsending msgs:\n" + dumpMessages(msgs)); } synchronized (msgs) { stopTimer(); if (msgs.size() == 0) { return; } for (Iterator it = msgs.entrySet().iterator(); it.hasNext(); ) { entry = (Map.Entry) it.next(); dest = (IpAddress) entry.getKey(); addr = dest.getIpAddress(); port = dest.getPort(); l = (List) entry.getValue(); try { out_stream.reset(); // BufferedOutputStream bos=new BufferedOutputStream(out_stream); out_stream.write(Version.version_id, 0, Version.version_id.length); // write the version // bos.write(Version.version_id, 0, Version.version_id.length); // write the version out = new ObjectOutputStream(out_stream); // out=new ObjectOutputStream(bos); l.writeExternal(out); out.close(); // needed if out buffers its output to out_stream data = out_stream.toByteArray(); doSend(data, addr, port); } catch (IOException e) { Trace.error( "UDP.BundlingOutgoingPacketHandle.bundleAndSend()", "exception sending msg (to dest=" + dest + "): " + e); } } msgs.clear(); } }
/** * \ Draw saved State (color dots on panel) on WhiteBoard * * @param outstream * @throws IOException */ public void writeState(OutputStream outstream) throws IOException { if (state == null) return; synchronized (state) { DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(outstream)); // DataOutputStream dos=new DataOutputStream(outstream); dos.writeInt(state.size()); for (Map.Entry<Point, Color> entry : state.entrySet()) { Point point = entry.getKey(); Color col = entry.getValue(); dos.writeInt(point.x); dos.writeInt(point.x); dos.writeInt(col.getRGB()); } dos.flush(); System.out.println("wrote " + state.size() + " elements"); } }
@ManagedOperation(description = "Reads data from local caches and dumps them to a file") public void dumpCache(String output_filename) throws Exception { Map<Address, PhysicalAddress> cache_contents = (Map<Address, PhysicalAddress>) down_prot.down(new Event(Event.GET_LOGICAL_PHYSICAL_MAPPINGS, false)); List<PingData> list = new ArrayList<>(cache_contents.size()); for (Map.Entry<Address, PhysicalAddress> entry : cache_contents.entrySet()) { Address addr = entry.getKey(); PhysicalAddress phys_addr = entry.getValue(); PingData data = new PingData(addr, true, UUID.get(addr), phys_addr).coord(addr.equals(local_addr)); list.add(data); } OutputStream out = new FileOutputStream(output_filename); write(list, out); }
/** Draw the entire panel from the state */ @SuppressWarnings("rawtypes") public void drawState() { // clear(); Map.Entry entry; Point pt; Color col; synchronized (state) { for (Iterator it = state.entrySet().iterator(); it.hasNext(); ) { entry = (Map.Entry) it.next(); pt = (Point) entry.getKey(); col = (Color) entry.getValue(); gr.setColor(col); gr.fillOval(pt.x, pt.y, 10, 10); } } repaint(); }
protected void addResponse(PingData rsp, boolean overwrite) { synchronized (ping_responses) { for (Iterator<Map.Entry<Long, Responses>> it = ping_responses.entrySet().iterator(); it.hasNext(); ) { Map.Entry<Long, Responses> entry = it.next(); long timestamp = entry.getKey(); Responses rsps = entry.getValue(); rsps.addResponse(rsp, overwrite); if (rsps.isDone() || TimeUnit.MILLISECONDS.convert(System.nanoTime() - timestamp, TimeUnit.NANOSECONDS) > discovery_rsp_expiry_time) { it.remove(); rsps.done(); } } } }
/** * Removes responses which are done or whose timeout has expired (in the latter case, an expired * response is marked as done) */ @ManagedOperation(description = "Removes expired or completed responses") public void weedOutCompletedDiscoveryResponses() { synchronized (ping_responses) { for (Iterator<Map.Entry<Long, Responses>> it = ping_responses.entrySet().iterator(); it.hasNext(); ) { Map.Entry<Long, Responses> entry = it.next(); long timestamp = entry.getKey(); Responses rsps = entry.getValue(); if (rsps.isDone() || TimeUnit.MILLISECONDS.convert(System.nanoTime() - timestamp, TimeUnit.NANOSECONDS) > discovery_rsp_expiry_time) { it.remove(); rsps.done(); } } } }
/** * Removed rejected merge requests from merge_rsps and coords. This method has a lock on * merge_rsps */ private void removeRejectedMergeRequests(Collection<Address> coords) { int num_removed = 0; for (Iterator<Map.Entry<Address, MergeData>> it = merge_rsps.getResults().entrySet().iterator(); it.hasNext(); ) { Map.Entry<Address, MergeData> entry = it.next(); MergeData data = entry.getValue(); if (data.merge_rejected) { if (data.getSender() != null) coords.remove(data.getSender()); it.remove(); num_removed++; } } if (num_removed > 0) { if (log.isTraceEnabled()) log.trace(gms.local_addr + ": removed " + num_removed + " rejected merge responses"); } }
protected void handleView(View view) { this.view = view; if (log.isDebugEnabled()) log.debug("view=" + view); List<Address> members = view.getMembers(); for (Map.Entry<String, ServerLock> entry : server_locks.entrySet()) { String lock_name = entry.getKey(); ServerLock server_lock = entry.getValue(); Lock lock = _getLock(lock_name); lock.lock(); try { server_lock.handleView(members); if (server_lock.isEmpty() && server_lock.current_owner == null && server_lock.condition.queue.isEmpty()) server_locks.remove(lock_name); } finally { lock.unlock(); } } }
@ManagedOperation(description = "Dumps all locks") public String printLocks() { StringBuilder sb = new StringBuilder(); sb.append("server locks:\n"); for (Map.Entry<String, ServerLock> entry : server_locks.entrySet()) { sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); } sb.append("\nmy locks: "); boolean first_element = true; for (Map.Entry<String, Map<Owner, ClientLock>> entry : client_locks.entrySet()) { if (first_element) first_element = false; else sb.append(", "); sb.append(entry.getKey()).append(" ("); Map<Owner, ClientLock> owners = entry.getValue(); boolean first = true; for (Map.Entry<Owner, ClientLock> entry2 : owners.entrySet()) { if (first) first = false; else sb.append(", "); sb.append(entry2.getKey()); ClientLock cl = entry2.getValue(); if (!cl.acquired || cl.denied) sb.append(", unlocked"); } sb.append(")"); } return sb.toString(); }
/** * Removes all members from a given view which don't have us in their view * (https://jira.jboss.org/browse/JGRP-1061). Example: * * <pre> * A: AB * B: AB * C: ABC * </pre> * * becomes * * <pre> * A: AB * B: AB * C: C // A and B don't have C in their views * </pre> * * @param map A map of members and their associated views */ public static void sanitizeViews(Map<Address, View> map) { if (map == null) return; for (Map.Entry<Address, View> entry : map.entrySet()) { Address key = entry.getKey(); Collection<Address> members = new ArrayList<Address>(entry.getValue().getMembers()); boolean modified = false; for (Iterator<Address> it = members.iterator(); it.hasNext(); ) { Address val = it.next(); if (val.equals(key)) // we can always talk to ourself ! continue; View view = map.get(val); final Collection<Address> tmp_mbrs = view != null ? view.getMembers() : null; if (tmp_mbrs != null && !tmp_mbrs.contains(key)) { it.remove(); modified = true; } } if (modified) { View old_view = entry.getValue(); entry.setValue(new View(old_view.getVid(), members)); } } }
@ManagedOperation( description = "Closes connections that have been idle for more than conn_expiry_timeout ms") public void reapIdleConnections() { if (conn_expiry_timeout <= 0) return; // remove expired connections from send_table for (Map.Entry<Address, SenderEntry> entry : send_table.entrySet()) { SenderEntry val = entry.getValue(); long age = val.age(); if (age >= conn_expiry_timeout) { removeSendConnection(entry.getKey()); if (log.isDebugEnabled()) log.debug( local_addr + ": removed expired connection for " + entry.getKey() + " (" + age + " ms old) from send_table"); } } // remove expired connections from recv_table for (Map.Entry<Address, ReceiverEntry> entry : recv_table.entrySet()) { ReceiverEntry val = entry.getValue(); long age = val.age(); if (age >= conn_expiry_timeout) { removeReceiveConnection(entry.getKey()); if (log.isDebugEnabled()) log.debug( local_addr + ": removed expired connection for " + entry.getKey() + " (" + age + " ms old) from recv_table"); } } }
@ManagedOperation public String printConnections() { StringBuilder sb = new StringBuilder(); if (!send_table.isEmpty()) { sb.append("send connections:\n"); for (Map.Entry<Address, SenderEntry> entry : send_table.entrySet()) { sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); } } if (!recv_table.isEmpty()) { sb.append("\nreceive connections:\n"); for (Map.Entry<Address, ReceiverEntry> entry : recv_table.entrySet()) { sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n"); } } return sb.toString(); }
@SuppressWarnings("unchecked") public Object up(Event evt) { switch (evt.getType()) { case Event.MSG: Message msg = (Message) evt.getArg(); PingHeader hdr = (PingHeader) msg.getHeader(this.id); if (hdr == null) return up_prot.up(evt); if (is_leaving) return null; // prevents merging back a leaving member // (https://issues.jboss.org/browse/JGRP-1336) PingData data = readPingData(msg.getRawBuffer(), msg.getOffset(), msg.getLength()); Address logical_addr = data != null ? data.getAddress() : msg.src(); switch (hdr.type) { case PingHeader.GET_MBRS_REQ: // return Rsp(local_addr, coord) if (cluster_name == null || hdr.cluster_name == null) { log.warn( "cluster_name (%s) or cluster_name of header (%s) is null; passing up discovery " + "request from %s, but this should not be the case", cluster_name, hdr.cluster_name, msg.src()); } else { if (!cluster_name.equals(hdr.cluster_name)) { log.warn( "%s: discarding discovery request for cluster '%s' from %s; " + "our cluster name is '%s'. Please separate your clusters properly", logical_addr, hdr.cluster_name, msg.src(), cluster_name); return null; } } // add physical address and logical name of the discovery sender (if available) to the // cache if (data != null) { addDiscoveryResponseToCaches( logical_addr, data.getLogicalName(), data.getPhysicalAddr()); discoveryRequestReceived(msg.getSrc(), data.getLogicalName(), data.getPhysicalAddr()); addResponse(data, false); } if (return_entire_cache) { Map<Address, PhysicalAddress> cache = (Map<Address, PhysicalAddress>) down(new Event(Event.GET_LOGICAL_PHYSICAL_MAPPINGS)); if (cache != null) { for (Map.Entry<Address, PhysicalAddress> entry : cache.entrySet()) { Address addr = entry.getKey(); // JGRP-1492: only return our own address, and addresses in view. if (addr.equals(local_addr) || members.contains(addr)) { PhysicalAddress physical_addr = entry.getValue(); sendDiscoveryResponse( addr, physical_addr, UUID.get(addr), msg.getSrc(), isCoord(addr)); } } } return null; } // Only send a response if hdr.mbrs is not empty and contains myself. Otherwise always // send my info Collection<? extends Address> mbrs = data != null ? data.mbrs() : null; boolean send_response = mbrs == null || mbrs.contains(local_addr); if (send_response) { PhysicalAddress physical_addr = (PhysicalAddress) down(new Event(Event.GET_PHYSICAL_ADDRESS, local_addr)); sendDiscoveryResponse( local_addr, physical_addr, UUID.get(local_addr), msg.getSrc(), is_coord); } return null; case PingHeader.GET_MBRS_RSP: // add physical address (if available) to transport's cache if (data != null) { log.trace("%s: received GET_MBRS_RSP from %s: %s", local_addr, msg.src(), data); handleDiscoveryResponse(data, msg.src()); } return null; default: log.warn("got PING header with unknown type %d", hdr.type); return null; } case Event.FIND_MBRS: return findMembers( (List<Address>) evt.getArg(), false, true); // this is done asynchronously } return up_prot.up(evt); }