public void testRefcount2() throws Exception { Prot p1 = new Prot("P1"), p2 = new Prot("P2"); fc1 = new ForkChannel(ch, "stack", "fc1", p1, p2); fc2 = new ForkChannel(ch, "stack", "fc2"); // uses p1 and p2 from fc1 fc3 = new ForkChannel(ch, "stack", "fc3"); // uses p1 and p2 from fc1 assert p1.inits == 1 && p2.inits == 1; FORK fork = (FORK) ch.getProtocolStack().findProtocol(FORK.class); Protocol prot = fork.get("stack"); ForkProtocolStack fork_stack = (ForkProtocolStack) getProtStack(prot); int inits = fork_stack.getInits(); assert inits == 3; ch.connect(CLUSTER); fc1.connect(CLUSTER); int connects = fork_stack.getConnects(); assert connects == 1; assert p1.starts == 1 && p2.starts == 1; fc2.connect(CLUSTER); fc3.connect(CLUSTER); connects = fork_stack.getConnects(); assert connects == 3; assert p1.starts == 1 && p2.starts == 1; fc3.disconnect(); fc2.disconnect(); assert p1.starts == 1 && p2.starts == 1; assert p1.stops == 0 && p2.stops == 0; fc1.disconnect(); assert p1.starts == 1 && p2.starts == 1; assert p1.stops == 1 && p2.stops == 1; Util.close(fc3, fc2); assert p1.destroys == 0 && p2.destroys == 0; Util.close(fc1); assert p1.destroys == 1 && p2.destroys == 1; }
protected void getStateFromMainAndForkChannels(Event evt) { final OutputStream out = (OutputStream) evt.getArg(); try (DataOutputStream dos = new DataOutputStream(out)) { getStateFrom(null, up_prot, null, null, dos); // now fetch state from all fork channels for (Map.Entry<String, Protocol> entry : fork_stacks.entrySet()) { String stack_name = entry.getKey(); Protocol prot = entry.getValue(); ForkProtocolStack fork_stack = getForkStack(prot); for (Map.Entry<String, JChannel> en : fork_stack.getForkChannels().entrySet()) { String fc_name = en.getKey(); JChannel fc = en.getValue(); getStateFrom(fc, null, stack_name, fc_name, dos); } } } catch (Throwable ex) { log.error("%s: failed fetching state from main channel", local_addr, ex); } }
protected void setStateInMainAndForkChannels(InputStream in) { try (DataInputStream input = new DataInputStream(in)) { for (; ; ) { String stack_name = Bits.readString(input); String ch_name = Bits.readString(input); int len = input.readInt(); if (len > 0) { byte[] data = new byte[len]; in.read(data, 0, len); ByteArrayInputStream tmp = new ByteArrayInputStream(data, 0, len); if (stack_name == null && ch_name == null) up_prot.up(new Event(Event.STATE_TRANSFER_INPUTSTREAM, tmp)); else { Protocol prot = fork_stacks.get(stack_name); if (prot == null) { log.warn( "%s: fork stack %s not found, dropping state for %s:%s", local_addr, stack_name, stack_name, ch_name); continue; } ForkProtocolStack fork_stack = getForkStack(prot); JChannel fork_ch = fork_stack.get(ch_name); if (fork_ch == null) { log.warn( "%s: fork channel %s not found, dropping state for %s:%s", local_addr, ch_name, stack_name, ch_name); continue; } fork_ch.up(new Event(Event.STATE_TRANSFER_INPUTSTREAM, tmp)); } } } } catch (EOFException eof) { } catch (Throwable ex) { log.error("%s: failed setting state in main channel", local_addr, ex); } }
/** * Returns the fork stack for fork_stack_id (if exitstent), or creates a new fork-stack from * protocols and adds it into the hashmap of fork-stack (key is fork_stack_id). Method init() will * be called on each protocol, from bottom to top. * * @param fork_stack_id The key under which the new fork-stack should be added to the fork-stacks * hashmap * @param protocols A list of protocols from <em>bottom to top</em> to be inserted. They will be * sandwiched between ForkProtocolStack (top) and ForkProtocol (bottom). The list can be empty * (or null) in which case we won't create any protocols, but still have a separate fork-stack * inserted. * @param initialize If false, the ref count 'inits' will not get incremented and init() won't be * called. This is needed when creating a fork stack from an XML config inside of the FORK * protocol. The protocols in the fork stack will only get initialized on the first * ForkChannel creation * @return The new {@link ForkProtocolStack}, or the existing stack (if present) */ public synchronized ProtocolStack createForkStack( String fork_stack_id, List<Protocol> protocols, boolean initialize) throws Exception { Protocol bottom; if ((bottom = get(fork_stack_id)) != null) { ForkProtocolStack retval = getForkStack(bottom); return initialize ? retval.incrInits() : retval; } List<Protocol> prots = new ArrayList<>(); prots.add( bottom = new ForkProtocol(fork_stack_id) .setDownProtocol(this)); // add a ForkProtocol as bottom protocol if (protocols != null) prots.addAll(protocols); ForkProtocolStack fork_stack = (ForkProtocolStack) new ForkProtocolStack(getUnknownForkHandler(), prots, fork_stack_id) .setChannel(this.stack.getChannel()); fork_stack.init(); if (initialize) fork_stack.incrInits(); fork_stacks.put(fork_stack_id, bottom); return fork_stack; }
public void testRefcount() throws Exception { FORK fork = (FORK) ch.getProtocolStack().findProtocol(FORK.class); Protocol prot = fork.get("stack"); assert prot == null; fc1 = new ForkChannel(ch, "stack", "fc1"); prot = fork.get("stack"); assert prot != null; ForkProtocolStack fork_stack = (ForkProtocolStack) getProtStack(prot); int inits = fork_stack.getInits(); assert inits == 1 : "inits is " + inits + "(expected 1)"; fc2 = new ForkChannel(ch, "stack", "fc2"); // uses the same fork stack "stack" inits = fork_stack.getInits(); assert inits == 2 : "inits is " + inits + "(expected 2)"; ch.connect(CLUSTER); fc1.connect(CLUSTER); int connects = fork_stack.getConnects(); assert connects == 1 : "connects is " + connects + "(expected 1)"; fc1.connect(CLUSTER); // duplicate connect() connects = fork_stack.getConnects(); assert connects == 1 : "connects is " + connects + "(expected 1)"; fc2.connect(CLUSTER); connects = fork_stack.getConnects(); assert connects == 2 : "connects is " + connects + "(expected 2)"; fc2.disconnect(); fc2.disconnect(); // duplicate disconnect() ! connects = fork_stack.getConnects(); assert connects == 1 : "connects is " + connects + "(expected 1)"; Util.close(fc2); inits = fork_stack.getInits(); assert inits == 1 : "inits is " + inits + "(expected 1)"; Util.close(fc2); // duplicate close() inits = fork_stack.getInits(); assert inits == 1 : "inits is " + inits + "(expected 1)"; Util.close(fc1); connects = fork_stack.getConnects(); assert connects == 0 : "connects is " + connects + "(expected 0)"; inits = fork_stack.getInits(); assert inits == 0 : "inits is " + inits + "(expected 0)"; prot = fork.get("stack"); assert prot == null; }