use of com.cinchapi.concourse.Concourse in project concourse by cinchapi.
the class CON669 method testConsistencyOfWideReadsWithConcurrentWrites.
@Test
public void testConsistencyOfWideReadsWithConcurrentWrites() throws Exception {
int threads = 10;
ConnectionPool connections = ConnectionPool.newCachedConnectionPool(SERVER_HOST, SERVER_PORT, "admin", "admin");
try {
client.set("count", 1L, 1);
AtomicBoolean done = new AtomicBoolean(false);
AtomicBoolean passed = new AtomicBoolean(true);
Thread reader = new Thread(() -> {
while (!done.get()) {
Concourse con = connections.request();
try {
Assert.assertFalse(con.select(1).get("count").isEmpty());
} catch (Exception e) {
e.printStackTrace();
passed.set(false);
} finally {
connections.release(con);
}
}
});
reader.start();
for (int i = 0; i < threads; ++i) {
Thread t = new Thread(() -> {
while (!done.get()) {
Concourse con = connections.request();
try {
long expected = (long) con.select(1).get("count").iterator().next();
con.verifyAndSwap("count", expected, 1, Time.now());
} catch (Exception e) {
e.printStackTrace();
passed.set(false);
} finally {
connections.release(con);
}
}
});
t.start();
}
Threads.sleep(3000);
done.set(true);
Assert.assertTrue(passed.get());
} finally {
while (!connections.isClosed()) {
try {
connections.close();
} catch (IllegalStateException e) {
Threads.sleep(100);
}
}
}
}
use of com.cinchapi.concourse.Concourse in project concourse by cinchapi.
the class CON669 method testConcurrentAtomicWritesToDifferentKeysInRecord.
@Test
public void testConcurrentAtomicWritesToDifferentKeysInRecord() {
Concourse client2 = Concourse.copyExistingConnection(client);
try {
client.stage();
client.add("a", "a", 1);
client2.stage();
client2.add("b", "b", 1);
Assert.assertTrue(client.commit());
Assert.assertTrue(client2.commit());
} finally {
client2.exit();
}
}
use of com.cinchapi.concourse.Concourse in project concourse by cinchapi.
the class ConcourseServerTest method testGetEngineRaceCondition.
@Test
public void testGetEngineRaceCondition() throws TException, InterruptedException {
// CON-673
int port = Networking.getOpenPort();
String env = "test";
String buffer = TestData.getTemporaryTestDir();
String db = TestData.getTemporaryTestDir();
server = ConcourseServer.create(port, buffer, db);
server.spawn();
try {
AccessToken token = server.login(ByteBuffers.fromUtf8String("admin"), ByteBuffers.fromUtf8String("admin"), env);
for (int i = 0; i < 10000; ++i) {
server.addKeyValue(TestData.getSimpleString(), TestData.getTObject(), token, null, env);
}
server.stop();
server = ConcourseServer.create(port, buffer, db);
server.spawn();
int threads = 20;
CountDownLatch latch = new CountDownLatch(threads);
for (int i = 0; i < threads; ++i) {
Thread t = new Thread(() -> {
Concourse client = Concourse.at().port(port).environment(env).connect();
client.exit();
latch.countDown();
});
t.start();
}
latch.await();
Assert.assertEquals(2, server.numEnginesInitialized.get());
} finally {
server.stop();
}
}
use of com.cinchapi.concourse.Concourse in project concourse by cinchapi.
the class ConcourseAccount method debit.
@Override
public boolean debit(String charge, double amount) {
Preconditions.checkArgument(amount > 0);
Concourse concourse = Constants.CONCOURSE_CONNECTIONS.request();
try {
concourse.stage();
if (withdrawImpl(concourse, amount)) {
// By using the #add method, we can store multiple charges in
// the record at the same time
concourse.add("charges", charge, id);
return concourse.commit();
} else {
concourse.abort();
return false;
}
} catch (TransactionException e) {
concourse.abort();
return false;
} finally {
Constants.CONCOURSE_CONNECTIONS.release(concourse);
}
}
use of com.cinchapi.concourse.Concourse in project concourse by cinchapi.
the class ConcourseAccount method deposit.
@Override
public boolean deposit(double amount) {
Preconditions.checkArgument(amount > 0);
// This implementation uses verifyAndSwap to atomically increment the
// account balance (without a using a transaction!) which ensures that
// money isn't lost if two people make a deposit at the same time.
Concourse concourse = Constants.CONCOURSE_CONNECTIONS.request();
try {
boolean incremented = false;
while (!incremented) {
double balance = concourse.get("balance", id);
double newBalance = balance + amount;
if (concourse.verifyAndSwap("balance", balance, id, newBalance)) {
incremented = true;
} else {
// initial read. If that happens, we simply retry
continue;
}
}
return true;
} finally {
Constants.CONCOURSE_CONNECTIONS.release(concourse);
}
}
Aggregations