neo4j-contrib / neoclipse

Graph Database Tool
218 stars 136 forks source link

Cypher Editor doesn't see uncommited changes #24

Closed nawroth closed 12 years ago

nawroth commented 12 years ago

When changing the graph, the cypher queries won't include the current state until it's commited.

Different views in Neoclipse should be consistent (that is, operate on the same view of the data). To achieve this the application was designed to execute all Neo4j operations in one single transactional context. This goes for read operations as well, or they won't pick up uncommited changes.

Otherwise, the Cypher Editor is really cool :-)

nrkkalyan commented 12 years ago

Hi Andres,

Thanks for your comment. I am executing the query on the same GraphDatabaseService instance which is used for creating nodes or relations in the graph view.

All I am doing to get the query results is : ExecutionEngine engine = new ExecutionEngine( graphDb ); executionResult = engine.execute( cypherQuery ); I don't know if I am missing something, i.e transaction context or anything. Would be great if I can get some guide in this regard.

Kalyan

On Mon, Jan 23, 2012 at 1:21 PM, Anders Nawroth < reply@reply.github.com

wrote:

When changing the graph, the cypher queries won't include the current state until it's commited.

Different views in Neoclipse should be consistent (that is, operate on the same view of the data). To achieve this the application was designed to execute all Neo4j operations in one single transactional context. This goes for read operations as well, or they won't pick up uncommited changes.

Otherwise, the Cypher Editor is really cool :-)


Reply to this email directly or view it on GitHub: https://github.com/neo4j/neoclipse/issues/24

Thanks and Regards N Radhakrishna Kalyan

nawroth commented 12 years ago

Neo4j transactions are thread confined, so to make all operations happen in the same thread (and thus the same transactional context), I added a single-threaded exector service in this class: https://github.com/neo4j/neoclipse/blob/master/org.neo4j.neoclipse/src/main/java/org/neo4j/neoclipse/graphdb/GraphDbServiceManager.java

This means that the graphdb instance shouldn't be exposed to other threads, but only through submitting a GraphCallable or GraphRunnable. That is, the "public GraphDatabaseService getGraphDb()" method shouldn't really be there.

Looks like the execute* methods in that class were designed for the cases which for some reason has to live outside of the single-threaded DB thread. It could happen due to race conditions or deadlocks. There's currently a bug in there somewhere, it would probably be better if we can get rid of these methods, enforcing everything to be in the right thread. What's good with having them, is that it makes it easy to switch between the submitTask* methods and the execute* methods while experimenting with executing code in different threads :-)

Also note that the UI is executed in a single thread as well, so code executed in the DB thread can't invoke any UI operations directly. Instead, the submitDisplayTask method can be used. (not using it will make the UI fail right away)

What makes all of this a bit hard is that for example during a traversal, the UI thread also makes calls to get data for visualization (like getting the properties etc). This can lead to race conditions (I have one such test case somewhere). Maybe it would be better to return some kind of proxy objects and not real nodes/relationships (caching all properties and relationships when getting them from the DB, and writing back changes at commit),

nrkkalyan commented 12 years ago

Hi Andres,

Thank you for your explanation. I will do the changes as you mentioned. Will let you know the progress.

Kalyan

On Tue, Jan 24, 2012 at 10:48 AM, Anders Nawroth < reply@reply.github.com

wrote:

Neo4j transactions are thread confined, so to make all operations happen in the same thread (and thus the same transactional context), I added a single-threaded exector service in this class: https://github.com/neo4j/neoclipse/blob/master/org.neo4j.neoclipse/src/main/java/org/neo4j/neoclipse/graphdb/GraphDbServiceManager.java

This means that the graphdb instance shouldn't be exposed to other threads, but only through submitting a GraphCallable or GraphRunnable. That is, the "public GraphDatabaseService getGraphDb()" method shouldn't really be there.

Looks like the execute* methods in that class were designed for the cases which for some reason has to live outside of the single-threaded DB thread. It could happen due to race conditions or deadlocks. There's currently a bug in there somewhere, it would probably be better if we can get rid of these methods, enforcing everything to be in the right thread. What's good with having them, is that it makes it easy to switch between the submitTask* methods and the execute* methods while experimenting with executing code in different threads :-)

Also note that the UI is executed in a single thread as well, so code executed in the DB thread can't invoke any UI operations directly. Instead, the submitDisplayTask method can be used. (not using it will make the UI fail right away)

What makes all of this a bit hard is that for example during a traversal, the UI thread also makes calls to get data for visualization (like getting the properties etc). This can lead to race conditions (I have one such test case somewhere). Maybe it would be better to return some kind of proxy objects and not real nodes/relationships (caching all properties and relationships when getting them from the DB, and writing back changes at commit),


Reply to this email directly or view it on GitHub: https://github.com/neo4j/neoclipse/issues/24#issuecomment-3629814

Thanks and Regards N Radhakrishna Kalyan

nrkkalyan commented 12 years ago

Hi Andres,

I removed the method to return grapdbservice and instead I am now using

gsm.submitTask( new GraphRunnable() { @Override public void run( final GraphDatabaseService graphDb ) { ExecutionEngine engine = new ExecutionEngine( graphDb ); executionResult = engine.execute( cypherQuery ); . *.... .......

} }, "execute cypher query" ).get();* But still no luck. Still I am not able to get the uncommitted results. Will try again tomorrow. Let me know if you find any thing wrong. Kalyan On Tue, Jan 24, 2012 at 10:48 AM, Anders Nawroth < reply@reply.github.com > wrote: > > Neo4j transactions are thread confined, so to make all operations happen > in the same thread (and thus the same transactional context), I added a > single-threaded exector service in this class: > https://github.com/neo4j/neoclipse/blob/master/org.neo4j.neoclipse/src/main/java/org/neo4j/neoclipse/graphdb/GraphDbServiceManager.java > > This means that the graphdb instance shouldn't be exposed to other > threads, but only through submitting a GraphCallable or GraphRunnable. That > is, the "public GraphDatabaseService getGraphDb()" method shouldn't really > be there. > > Looks like the execute\* methods in that class were designed for the cases > which for some reason has to live outside of the single-threaded DB thread. > It could happen due to race conditions or deadlocks. There's currently a > bug in there somewhere, it would probably be better if we can get rid of > these methods, enforcing everything to be in the right thread. What's good > with having them, is that it makes it easy to switch between the > submitTask\* methods and the execute\* methods while experimenting with > executing code in different threads :-) > > Also note that the UI is executed in a single thread as well, so code > executed in the DB thread can't invoke any UI operations directly. Instead, > the submitDisplayTask method can be used. (not using it will make the UI > fail right away) > > What makes all of this a bit hard is that for example during a traversal, > the UI thread also makes calls to get data for visualization (like getting > the properties etc). This can lead to race conditions (I have one such test > case somewhere). Maybe it would be better to return some kind of proxy > objects and not real nodes/relationships (caching all properties and > relationships when getting them from the DB, and writing back changes at > commit), > > --- > > Reply to this email directly or view it on GitHub: > https://github.com/neo4j/neoclipse/issues/24#issuecomment-3629814 ## Thanks and Regards N Radhakrishna Kalyan
nawroth commented 12 years ago

I guess the problem is in the section then :-) Maybe you should go for a GraphCallable to collect the result set instead. Simply put, have as little code as possible inside the GraphRunnable/GraphCallable, do the rest outside of it. If you want some value produced in there, go for the GraphCallable.