use of org.jgroups.JChannel in project JGroups by belaban.
the class ClusterSplitLockTest method testClusterSplitImpl.
/**
* Performs a test where the specified downMember goes down when the member performed a lock operation on 50%
* of the locks. The coordinator should unlock all locks that were locked by the member that goes down. If the
* member that goes down is the coordinator the new channel coordinator should make sure the lock table is up-to-date.
*/
private void testClusterSplitImpl(final int downMember, Class<? extends Locking> locking_class) throws Exception {
setUp(locking_class);
CountDownLatch doneOnMemberThatWillGoDown = new CountDownLatch(1);
final int numLocks = 10;
final int halfway = numLocks / 2;
List<Future<?>> futures = new ArrayList<>();
/*
* All members perform the specified number of lock() operations. The
* 'downMember' disconnects half way
*/
for (int i = 0; i < MEMBERS; i++) {
final int mbrIdx = i;
final AtomicInteger unlockCount = new AtomicInteger(0);
for (int j = 0; j < numLocks; j++) {
final int lockNr = j;
if (mbrIdx == downMember) {
if (lockNr == halfway) {
futures.add(execs[downMember].submit(() -> {
try {
doneOnMemberThatWillGoDown.await();
log("Disconnecting member %s", memberName(downMember));
disconnectAndDestroy(downMember);
} catch (Exception e) {
throw new RuntimeException(e);
}
}));
}
if (lockNr >= halfway) {
break;
}
}
futures.add(execs[mbrIdx].submit(() -> {
Lock lock = lockServices[mbrIdx].getLock("testlock" + lockNr);
try {
if (!lock.tryLock(5, SECONDS)) {
if (mbrIdx == downMember) {
fail(String.format("Member %s failed to lock %s using tryLock in healthy situation.", memberName(mbrIdx), lockNr));
} else {
log("Failed to tryLock member:%s lock:%d LOCKS:\n%s", memberName(mbrIdx), lockNr, lockServices[mbrIdx].printLocks());
return;
}
} else {
log("Member %s locked %d (threadid: %d)", memberName(mbrIdx), lockNr, Thread.currentThread().getId());
}
} catch (InterruptedException ie) {
log("InterruptedException member:%s, lock:%d", memberName(mbrIdx), lockNr, ie);
fail("Interrupted on tryLock " + memberName(mbrIdx) + " - " + lockNr);
}
try {
Thread.sleep(30);
} catch (InterruptedException e) {
fail("Interrupted while sleeping.");
} finally {
lock.unlock();
log("Unlocked lock %d by member %s (threadid: %d)", lockNr, memberName(mbrIdx), Thread.currentThread().getId());
if (mbrIdx == downMember && halfway == unlockCount.incrementAndGet()) {
log("setting doneOnMemberThatWillGoDown flag");
doneOnMemberThatWillGoDown.countDown();
}
}
}));
}
}
/* wait for the chaos to disappear */
for (Future<?> fut : futures) {
fut.get();
}
StringBuilder locksOverview = new StringBuilder("\n==== first run done ====\n");
for (int i = 0; i < MEMBERS; i++) {
locksOverview.append(String.format("Locks on member %s:\n%s\n", memberName(i), lockServices[i].printLocks()));
}
locksOverview.append("\n========================");
log(locksOverview.toString());
/*
* All locks should be unlocked at this point so no try lock request
* should fail
*/
Thread.sleep(2000);
log("==== Checking if tryLock succeeds for all locks on all remaining members =====");
for (int i = 0; i < MEMBERS; i++) {
if (i == downMember) {
continue;
}
for (int j = 0; j < numLocks; j++) {
Lock l = lockServices[i].getLock("testlock" + j);
if (!l.tryLock()) {
logError("Failed to acquire lock on %d by member %s", j, memberName(i));
Address coord = channels[i].getView().getCoord();
int count = 0;
for (JChannel c : channels) {
if (null != c.getAddress() && c.getAddress().equals(coord)) {
logError("Lock table for %s (coord):\n%s", coord, lockServices[count].printLocks());
break;
}
count++;
}
fail(String.format("Member %s can't lock:%d", memberName(i), j));
}
l.unlock();
}
}
}
use of org.jgroups.JChannel in project JGroups by belaban.
the class ClusterSplitLockTest method setUp.
protected void setUp(Class<? extends Locking> locking_class) throws Exception {
for (int i = 0; i < MEMBERS; i++) {
Locking lock_prot = locking_class.getDeclaredConstructor().newInstance().level("debug");
if (lock_prot instanceof CENTRAL_LOCK)
((CENTRAL_LOCK) lock_prot).setNumberOfBackups(2);
Protocol[] stack = Util.getTestStack(lock_prot);
channels[i] = new JChannel(stack);
lockServices[i] = new LockService(channels[i]);
channels[i].setName(memberName(i));
channels[i].connect("TEST");
execs[i] = Executors.newCachedThreadPool();
if (i == 0)
Util.sleep(500);
}
Util.waitUntilAllChannelsHaveSameView(10000, 1000, channels);
// Make sure A is coordinator, because we blindly assume it is in the tests below.
assertEquals(channels[0].getAddress(), channels[0].getView().getCoord());
}
use of org.jgroups.JChannel in project JGroups by belaban.
the class ConnectStressTest method testConcurrentJoining.
public void testConcurrentJoining() throws Exception {
for (int i = 0; i < NUM; i++) {
threads[i] = new MyThread(channels[i], i + 1, barrier);
threads[i].start();
}
// causes all threads to call Channel.connect()
barrier.await();
System.out.println("*** Starting the connect phase ***");
long target_time = System.currentTimeMillis() + 60000L;
while (System.currentTimeMillis() < target_time) {
View view = channels[0].getView();
if (view != null) {
int size = view.size();
System.out.println("channel[0].view has " + size + " members (expected: " + NUM + ")");
if (size >= NUM)
break;
}
Util.sleep(1000L);
}
for (JChannel ch : channels) {
View view = ch.getView();
if (view != null)
System.out.println(ch.getName() + ": size=" + view.size() + ", view-id: " + view.getViewId());
}
for (JChannel ch : channels) {
View view = ch.getView();
int size = view != null ? view.size() : 0;
assert view != null && size == NUM : "view doesn't have size of " + NUM + " (has " + size + "): " + view;
}
}
use of org.jgroups.JChannel in project JGroups by belaban.
the class BaseLeaveTest method testLeaveOfSecondHalfWithCoordLeaving.
/**
* The second half of the cluster (6,7,8,9,10) sends LEAVE requests to 1, but 1 leaves before they get a response.
* Requires them to resend their LEAVE requests to 2 on the view change when 2 takes over as coord.
*/
public void testLeaveOfSecondHalfWithCoordLeaving() throws Exception {
setup(NUM);
Stream.of(channels).forEach(ch -> ch.getProtocolStack().removeProtocols(FailureDetection.class, FD_SOCK.class));
Comparator<GmsImpl.Request> comp = Comparator.comparingInt(GmsImpl.Request::getType).reversed();
GMS gms = channels[0].getProtocolStack().findProtocol(GMS.class);
ViewHandler vh = gms.getViewHandler();
MyViewHandler my_vh = new MyViewHandler(gms, vh.reqProcessor(), GmsImpl.Request::canBeProcessedTogether, comp, 6).processing(true);
setViewHandler(my_vh, gms);
testConcurrentLeaves(0, 5, 6, 7, 8, 9);
my_vh.processing(false);
setViewHandler(vh, gms);
assert Stream.of(0, 5, 6, 7, 8, 9).map(i -> channels[i]).allMatch(JChannel::isClosed);
assert Stream.of(1, 2, 3, 4).map(i -> channels[i]).allMatch(JChannel::isConnected);
assert Stream.of(1, 2, 3, 4).map(i -> channels[i]).allMatch(ch -> ch.getView().getCoord().equals(channels[1].getAddress()));
}
use of org.jgroups.JChannel in project JGroups by belaban.
the class TCPPING_Test method testSettingInitialHostsProgrammatically.
/**
* Tests https://issues.jboss.org/browse/JGRP-2168
*/
public void testSettingInitialHostsProgrammatically() throws Exception {
TCP transport = new TCP();
transport.setBindAddress(InetAddress.getLoopbackAddress());
transport.setBindPort(9600);
TCPPING ping = new TCPPING();
TCPGOSSIP gossip = new TCPGOSSIP();
List<InetSocketAddress> gossip_router = Collections.singletonList(new InetSocketAddress(InetAddress.getLoopbackAddress(), 12000));
gossip.setInitialHosts(gossip_router);
ping.setInitialHosts2(Collections.singletonList(new IpAddress(transport.getBindAddress(), transport.getBindPort())));
ch = new JChannel(transport, ping, gossip);
assert !ping.getInitialHosts().isEmpty() : "No initial hosts!";
assert !gossip.getInitialHosts().isEmpty() : "no initial hosts!";
}
Aggregations