[
https://issues.apache.org/jira/browse/CASSANDRA-11048?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15117678#comment-15117678
]
Henry Manasseh commented on CASSANDRA-11048:
--------------------------------------------
Is there an existing muti-threaded test suite for Cassandra which could be
extended for this fix? This seems to be more of an integration test in that it
would require a live Cassandra instance with predictable test data. I am not
familiar with the code but I am interested in reviewing it and understanding
how you test multi-threaded code in Cassandra.
I am able to replicate the issue every time (just clicking on a webapp page 4-8
times makes my new application fail).
I wrote this code to replicate and confirmed the patch does fix the issue.
import com.datastax.driver.core.*;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import java.util.Iterator;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
// Load some data with: ./tools/bin/cassandra-stress write n=1000 cl=one -mode
native cql3 -log file=~/temp/create_schema.log
public class JsonBug {
public static void main(String [] arguments) {
String node = "127.0.0.1";
Cluster cluster = Cluster.builder()
.addContactPoint(node)
.build();
Metadata metadata = cluster.getMetadata();
System.out.printf("Connected to cluster: %s\n",
metadata.getClusterName());
for ( Host host : metadata.getAllHosts() ) {
System.out.printf("Datacenter: %s; Host: %s; Rack: %s\n",
host.getDatacenter(), host.getAddress(), host.getRack());
}
final Session session = cluster.connect("keyspace1");
final PreparedStatement prepStatement = session.prepare("select JSON *
from standard1");
ExecutorService executorService = Executors.newFixedThreadPool(250);
for(int i=0; i<100; i++) {
executorService.submit(new Runnable() {
public void run() {
BoundStatement boundStatement = new
BoundStatement(prepStatement);
ResultSet rs = session.execute(boundStatement);
Iterator<Row> rsIterator = rs.iterator();
JsonParser parser = new JsonParser();
while(rsIterator.hasNext()) {
Row row = rsIterator.next();
String jsonString = row.getString(0);
//System.out.println(jsonString);
JsonObject jsonObj = (JsonObject)
parser.parse(jsonString);
if(jsonObj.get("key") == null) System.out.println("No
key for " + jsonString + "\n");
if(jsonObj.get("\"C0\"") == null)
System.out.println("No C0 for " + jsonString + "\n");
if(jsonObj.get("\"C1\"") == null)
System.out.println("No C1 for " + jsonString + "\n");
if(jsonObj.get("\"C2\"") == null)
System.out.println("No C2 for " + jsonString + "\n");
if(jsonObj.get("\"C3\"") == null)
System.out.println("No C3 for " + jsonString + "\n");
if(jsonObj.get("\"C4\"") == null)
System.out.println("No C4for " + jsonString + "\n");
}
}
});
}
executorService.shutdown();
try {
executorService.awaitTermination(Long.MAX_VALUE,
TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
e.printStackTrace();
}
cluster.close();
}
}
> JSON queries are not thread safe
> --------------------------------
>
> Key: CASSANDRA-11048
> URL: https://issues.apache.org/jira/browse/CASSANDRA-11048
> Project: Cassandra
> Issue Type: Bug
> Reporter: Sergio Bossa
> Priority: Critical
> Labels: easyfix, newbie, patch
> Attachments:
> 0001-Fix-thread-unsafe-usage-of-JsonStringEncoder-see-CAS.patch
>
>
> {{org.apache.cassandra.cql3.Json}} uses a shared instance of
> {{JsonStringEncoder}} which is not thread safe (see 1), while
> {{JsonStringEncoder#getInstance()}} should be used (see 2).
> As a consequence, concurrent {{select JSON}} queries often produce wrong
> (sometimes unreadable) results.
> 1.
> http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.jackson/jackson-core-asl/1.9.2/org/codehaus/jackson/io/JsonStringEncoder.java
> 2.
> http://grepcode.com/file/repo1.maven.org/maven2/org.codehaus.jackson/jackson-core-asl/1.9.2/org/codehaus/jackson/io/JsonStringEncoder.java#JsonStringEncoder.getInstance%28%29
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)