Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
package org.umlg.sqlg.test.schema;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.tinkerpop.gremlin.structure.Edge;
import org.apache.tinkerpop.gremlin.structure.Graph;
import org.apache.tinkerpop.gremlin.structure.T;
import org.apache.tinkerpop.gremlin.structure.Vertex;
import org.junit.Assert;
import org.junit.Assume;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.umlg.sqlg.structure.SqlgGraph;
import org.umlg.sqlg.test.BaseTest;
import java.net.URL;
import java.util.HashSet;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import static java.util.concurrent.Executors.newFixedThreadPool;
import static org.junit.Assert.fail;
/**
* Date: 2014/09/24
* Time: 10:46 AM
*/
public class TestMultiThread extends BaseTest {
private Logger logger = LoggerFactory.getLogger(TestMultiThread.class.getName());
/**
* This test is a duplicate of TransactionTest.shouldSupportTransactionIsolationCommitCheck but with the schema created upfront else it deadlocks.
* @throws Exception
*/
@Test
public void shouldSupportTransactionIsolationCommitCheck() throws Exception {
Vertex v1 = this.sqlgGraph.addVertex();
this.sqlgGraph.tx().commit();
v1.remove();
this.sqlgGraph.tx().commit();
// the purpose of this test is to simulate gremlin server access to a graph instance, where one thread modifies
// the graph and a separate thread cannot affect the transaction of the first
final CountDownLatch latchCommittedInOtherThread = new CountDownLatch(1);
final CountDownLatch latchCommitInOtherThread = new CountDownLatch(1);
final AtomicBoolean noVerticesInFirstThread = new AtomicBoolean(false);
// this thread starts a transaction then waits while the second thread tries to commit it.
final Thread threadTxStarter = new Thread("thread1") {
@Override
public void run() {
TestMultiThread.this.sqlgGraph.addVertex();
latchCommitInOtherThread.countDown();
try {
latchCommittedInOtherThread.await();
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
TestMultiThread.this.sqlgGraph.tx().rollback();
// there should be no vertices here
noVerticesInFirstThread.set(!TestMultiThread.this.sqlgGraph.vertices().hasNext());
}
};
threadTxStarter.start();
// this thread tries to commit the transaction started in the first thread above.
final Thread threadTryCommitTx = new Thread("thread2") {
@Override
public void run() {
try {
latchCommitInOtherThread.await();
} catch (InterruptedException ie) {
throw new RuntimeException(ie);
}
// try to commit the other transaction
TestMultiThread.this.sqlgGraph.tx().commit();
latchCommittedInOtherThread.countDown();
}
};
threadTryCommitTx.start();
threadTxStarter.join();
threadTryCommitTx.join();
Assert.assertTrue(noVerticesInFirstThread.get());
assertVertexEdgeCounts(0, 0);
}
@Test
public void shouldExecuteWithCompetingThreads() throws InterruptedException {
final Graph graph = this.sqlgGraph;
int totalThreads = 250;
final AtomicInteger vertices = new AtomicInteger(0);
final AtomicInteger edges = new AtomicInteger(0);
final AtomicInteger completedThreads = new AtomicInteger(0);
CountDownLatch countDownLatch = new CountDownLatch(totalThreads);
for (int i = 0; i < totalThreads; i++) {
new Thread() {
@Override
public void run() {
try {
final Random random = new Random();
for (int i = 0; i < 100; i++) {
if (random.nextBoolean()) {
final Vertex a = graph.addVertex();
final Vertex b = graph.addVertex();
final Edge e = a.addEdge("friend", b);
vertices.getAndAdd(2);
a.property("test", this.getId());
b.property("blah", random.nextDouble());
e.property("bloop", random.nextInt());
edges.getAndAdd(1);
graph.tx().commit();
} else {
final Vertex a = graph.addVertex();
final Vertex b = graph.addVertex();
final Edge e = a.addEdge("friend", b);
a.property("test", this.getId());
b.property("blah", random.nextDouble());
e.property("bloop", random.nextInt());
if (random.nextBoolean()) {
graph.tx().commit();
vertices.getAndAdd(2);
edges.getAndAdd(1);
} else {
graph.tx().rollback();
}
}
}
completedThreads.getAndAdd(1);
logger.info("shouldExecuteWithCompetingThreads " + completedThreads.get());
} catch (Exception e) {
logger.error("failure", e);
fail(e.getMessage());
} finally {
countDownLatch.countDown();
}
}
}.start();
}
countDownLatch.await(5,TimeUnit.MINUTES);
Assert.assertEquals(completedThreads.get(), totalThreads);
System.out.println(vertices.get());
assertVertexEdgeCounts(vertices.get(), edges.get());
}
private static Consumer assertVertexEdgeCounts(final int expectedVertexCount, final int expectedEdgeCount) {
return (g) -> {
Assert.assertEquals(new Long(expectedVertexCount), g.traversal().V().count().next());
Assert.assertEquals(new Long(expectedEdgeCount), g.traversal().E().count().next());
};
}
@Test
public void testMultiThreadVertices() throws InterruptedException, ExecutionException {
Set tables = new ConcurrentSkipListSet<>();
ExecutorService executorService = newFixedThreadPool(10);
for (int j = 0; j < 100; j++) {
executorService.submit(() -> {
final Random random = new Random();
int randomInt = random.nextInt();
for (int i = 0; i < 10; i++) {
sqlgGraph.addVertex(T.label, "Person" + String.valueOf(randomInt), "name", String.valueOf(randomInt));
tables.add(randomInt);
}
sqlgGraph.tx().commit();
});
}
executorService.shutdown();
executorService.awaitTermination(6000, TimeUnit.SECONDS);
for (Integer i : tables) {
Assert.assertTrue(this.sqlgGraph.getSchemaManager().tableExist(this.sqlgGraph.getSqlDialect().getPublicSchema(), "V_Person" + String.valueOf(i)));
Assert.assertEquals(10, this.sqlgGraph.traversal().V().has(T.label, "Person" + String.valueOf(i)).has("name", String.valueOf(i)).count().next().intValue());
}
}
@Test
public void testMultiThreadEdges() throws InterruptedException, ExecutionException {
Vertex v1 = sqlgGraph.addVertex(T.label, "Person", "name", "0");
sqlgGraph.tx().commit();
Set tables = new ConcurrentSkipListSet<>();
ExecutorService executorService = newFixedThreadPool(10);
for (int j = 0; j < 100; j++) {
executorService.submit(() -> {
final Random random = new Random();
int randomInt = random.nextInt();
for (int i = 0; i < 10; i++) {
Vertex v2 = sqlgGraph.addVertex(T.label, "Person" + String.valueOf(randomInt), "name", String.valueOf(randomInt));
v1.addEdge("test" + String.valueOf(randomInt), v2);
tables.add(randomInt);
}
sqlgGraph.tx().commit();
});
}
executorService.shutdown();
executorService.awaitTermination(60, TimeUnit.SECONDS);
for (Integer i : tables) {
Assert.assertTrue(this.sqlgGraph.getSchemaManager().tableExist(this.sqlgGraph.getSqlDialect().getPublicSchema(), "V_Person" + String.valueOf(i)));
Assert.assertEquals(10, this.sqlgGraph.traversal().V().has(T.label, "Person" + String.valueOf(i)).has("name", String.valueOf(i)).count().next().intValue());
Assert.assertEquals(10, vertexTraversal(this.sqlgGraph, v1).out("test" + String.valueOf(i)).count().next().intValue());
}
}
@Test
public void testMultiThreadCreateSchemas() throws InterruptedException, ExecutionException {
Set schemas = new HashSet<>();
ExecutorService executorService = newFixedThreadPool(200);
for (int i = 0; i < 10_000; i++) {
Integer schema = new Random().nextInt(99);
schemas.add(schema);
Future f = executorService.submit(() -> {
this.sqlgGraph.getTopology().ensureSchemaExist("schema_" + schema);
this.sqlgGraph.tx().commit();
});
f.get();
}
executorService.shutdown();
executorService.awaitTermination(5, TimeUnit.SECONDS);
//+ 1 for the public schema and gui_schema i.e. globalUniqueIndex
Assert.assertEquals(schemas.size() + 2, this.sqlgGraph.getTopology().getSchemas().size());
}
/**
* test when each graph is created in its own thread, in distributed mode
*
* @throws Exception
*/
@Test
public void testMultipleGraphs() throws Exception {
URL sqlProperties = Thread.currentThread().getContextClassLoader().getResource("sqlg.properties");
try {
configuration = new PropertiesConfiguration(sqlProperties);
Assume.assumeTrue(configuration.getString("jdbc.url").contains("postgresql"));
configuration.addProperty("distributed", true);
if (!configuration.containsKey("jdbc.url"))
throw new IllegalArgumentException(String.format("SqlGraph configuration requires that the %s be set", "jdbc.url"));
} catch (ConfigurationException e) {
throw new RuntimeException(e);
}
ExecutorService executorService = newFixedThreadPool(100);
int loop = 400;
for (int i = 0; i < loop; i++) {
String n = "person" + i;
executorService.submit(() -> {
try {
try (SqlgGraph sqlgGraph1 = SqlgGraph.open(configuration)) {
final Random random = new Random();
if (random.nextBoolean()) {
Vertex person = sqlgGraph1.addVertex(T.label, "Person_True", "name", n);
Vertex address = sqlgGraph1.addVertex(T.label, "Address_True", "name", n);
person.addEdge("address_True", address, "name", n);
} else {
Vertex person = sqlgGraph1.addVertex(T.label, "Person", "name", n);
Vertex address = sqlgGraph1.addVertex(T.label, "Address", "name", n);
person.addEdge("address", address, "name", n);
}
sqlgGraph1.tx().commit();
}
} catch (Exception e) {
logger.error(e.getMessage(), e);
fail(e.getMessage());
}
});
}
executorService.shutdown();
executorService.awaitTermination(100, TimeUnit.SECONDS);
try (SqlgGraph sqlgGraph1 = SqlgGraph.open(configuration)) {
Assert.assertEquals(400, sqlgGraph1.traversal().V().hasLabel("Person_True").count().next().longValue() + sqlgGraph1.traversal().V().hasLabel("Person").count().next().longValue());
Assert.assertEquals(400, sqlgGraph1.traversal().V().hasLabel("Address_True").count().next().longValue() + sqlgGraph1.traversal().V().hasLabel("Address").count().next().longValue());
Assert.assertEquals(400, sqlgGraph1.traversal().E().hasLabel("address_True").count().next().longValue() + sqlgGraph1.traversal().E().hasLabel("address").count().next().longValue());
}
}
/**
* test when each graph is created in its own thread, in distributed mode
* each thread created a different label
*
* @throws Exception
*/
@Test
public void testMultipleGraphsMultipleLabels() throws Exception {
URL sqlProperties = Thread.currentThread().getContextClassLoader().getResource("sqlg.properties");
try {
configuration = new PropertiesConfiguration(sqlProperties);
Assume.assumeTrue(configuration.getString("jdbc.url").contains("postgresql"));
configuration.addProperty("distributed", true);
if (!configuration.containsKey("jdbc.url"))
throw new IllegalArgumentException(String.format("SqlGraph configuration requires that the %s be set", "jdbc.url"));
} catch (ConfigurationException e) {
e.printStackTrace();
fail(e.getMessage());
}
ExecutorService executorService = newFixedThreadPool(200);
int loop = 20;
for (int i = 0; i < loop; i++) {
String n = "person" + i;
executorService.submit(() -> {
try {
try (SqlgGraph sqlgGraph1 = SqlgGraph.open(configuration)) {
sqlgGraph1.addVertex(T.label, "Person" + n, "name", n);
sqlgGraph1.tx().commit();
}
} catch (Exception e) {
e.printStackTrace();
fail(e.getMessage());
}
});
}
executorService.shutdown();
executorService.awaitTermination(10, TimeUnit.SECONDS);
try (SqlgGraph sqlgGraph1 = SqlgGraph.open(configuration)) {
for (int i = 0; i < loop; i++) {
String n = "person" + i;
Assert.assertEquals(1, sqlgGraph1.traversal().V().hasLabel("Person" + n).count().next().longValue());
}
}
}
}