2015-02-10 5 views
1

Я пишу приложение Java с TinkerPop3. Он связывается с графиком Neo4j и отправляет запросы чтения/записи через Gremlin, используя библиотеки neo4j-gremlin 3.0.0.M7.Параллельные запросы gremlin-сервера и графика в java

Параллельно, я хотел бы сделать этот график доступным через HTTP, используя gremlin-server 3.0.0.M7. Отдельно эти операции работают отлично. Однако кажется, что это невозможно одновременно из-за того, что несколько соединений не разрешены (т. Е. Объект GremlinServer и код Java оба пытаются получить блокировку на графике).

Конечно, обходным путем может быть создание клиента из программы Java и подключение его к серверу. Тем не менее, я бы предпочел исключить коммуникационные издержки, которые это вводит.

Большой вопрос: возможно ли это?

Для полноты, вот мой минимальный код. Обратите внимание, что мой gremlin-server-neo4j.yaml относится к обычно включенному файлу neo4j-empty.properties, содержащему тот же каталог данных данных neo4j, что и объект Neo4jGraph в моем Java-коде (то есть /tmp/neo4j).

import com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph; 
import com.tinkerpop.gremlin.server.GremlinServer; 
import com.tinkerpop.gremlin.server.Settings;  

public class Main { 

    Neo4jGraph g; 
    GremlinServer s; 

    public static void main (String[] argv) { 
     new Main().start(); 
    } 

    private void start() { 

     try { 
      Settings settings = Settings.read(getClass().getResourceAsStream("/gremlin-server-neo4j.yaml")); 
      s = new GremlinServer(settings); 
      s.run(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 

     g = Neo4jGraph.open("/tmp/neo4j"); 

     // Gremlin code here 

     g.close(); 
     s.stop(); 
    } 
} 

И, наконец, исключение:

Exception in thread "main" java.lang.RuntimeException: Error starting org.neo4j.kernel.EmbeddedGraphDatabase, /tmp/neo4j 
    at com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph.<init>(Neo4jGraph.java:160) 
    at com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph.open(Neo4jGraph.java:175) 
    at com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph.open(Neo4jGraph.java:184) 
    at org.test.Main.start(Main.java:33) 
    at org.test.Main.main(Main.java:15) 
Caused by: java.lang.RuntimeException: Error starting org.neo4j.kernel.EmbeddedGraphDatabase, /tmp/neo4j 
    at org.neo4j.kernel.InternalAbstractGraphDatabase.run(InternalAbstractGraphDatabase.java:366) 
    at org.neo4j.kernel.EmbeddedGraphDatabase.<init>(EmbeddedGraphDatabase.java:59) 
    at org.neo4j.graphdb.factory.GraphDatabaseFactory$1.newDatabase(GraphDatabaseFactory.java:91) 
    at org.neo4j.graphdb.factory.GraphDatabaseBuilder.newGraphDatabase(GraphDatabaseBuilder.java:181) 
    at com.tinkerpop.gremlin.neo4j.structure.Neo4jGraph.<init>(Neo4jGraph.java:133) 
    ... 4 more 
Caused by: org.neo4j.kernel.lifecycle.LifecycleException: Component '[email protected]' was successfully initialized, but failed to start. Please see attached cause exception. 
    at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:513) 
    at org.neo4j.kernel.lifecycle.LifeSupport.start(LifeSupport.java:115) 
    at org.neo4j.kernel.InternalAbstractGraphDatabase.run(InternalAbstractGraphDatabase.java:343) 
    ... 8 more 
Caused by: org.neo4j.kernel.StoreLockException: Unable to obtain lock on store lock file: /tmp/neo4j/store_lock. Please ensure no other process is using this database, and that the directory is writable (required even for read-only access) 
    at org.neo4j.kernel.StoreLocker.checkLock(StoreLocker.java:82) 
    at org.neo4j.kernel.StoreLockerLifecycleAdapter.start(StoreLockerLifecycleAdapter.java:44) 
    at org.neo4j.kernel.lifecycle.LifeSupport$LifecycleInstance.start(LifeSupport.java:507) 
    ... 10 more 
Caused by: java.io.IOException: Unable to lock [email protected] 
    at org.neo4j.kernel.impl.nioneo.store.FileLock.wrapFileChannelLock(FileLock.java:38) 
    at org.neo4j.kernel.impl.nioneo.store.FileLock.getOsSpecificFileLock(FileLock.java:93) 
    at org.neo4j.kernel.DefaultFileSystemAbstraction.tryLock(DefaultFileSystemAbstraction.java:93) 
    at org.neo4j.kernel.StoreLocker.checkLock(StoreLocker.java:74) 
    ... 12 more 

ответ

2

Как вы нашли то, что вы пытаетесь сделать, не будет работать, так как два отдельных процесса не могут работать на встроенном Neo4jGraph. Как бы то ни было, вы не можете получить доступ к настроенным экземплярам графа из объекта GremlinServer, и я не уверен, что изменил бы это, поскольку я не совсем уверен, что это функция, которая была бы полезной для всех.

Мне кажется, что вам нужен способ «инициализировать» ваш экземпляр Graph. Если это так, то Gremlin Server предлагает способ сделать это. Вы можете предоставить сценарий инициализации в файле yaml (ниже приведен фрагмент от conf/gremlin-server-classic.yaml, который поставляется с дистрибутивом Gremlin Server).

scriptEngines: { 
    gremlin-groovy: { 
    imports: [java.lang.Math], 
    staticImports: [java.lang.Math.PI], 
    scripts: [scripts/generate-classic.groovy]}} 

Обратите внимание на ключ «скриптов», который позволяет вам отправлять файлы сценариев. Эти сценарии позволят вам получить доступ к «g» (или любым другим графикам, которые вы настроили). Для этого примера, scripts/generate-classic.groovy просто есть:

TinkerFactory.generateClassic(g) 

В этом случае вы можете сделать всю вашу инициализации работы на Graph, что в конечном итоге будет организован Gremlin Server, когда он начинается и может тогда просто начать все это в стандарте с bin/gremlin-server.sh.

+0

Спасибо за ваш быстрый ответ! Означает ли это, что сервер не будет работать до тех пор, пока указанные сценарии не будут завершены? В моем конкретном приложении я хотел бы выполнить скрипт, который работает одновременно с сервером, но, как я понимаю, такой скрипт предназначен только для этапа инициализации (удерживая блокировку до завершения, позволяя серверу захватывать блокировка впоследствии). Будет ли такой сценарий работать вечно, чтобы сервер никогда не начинался? – rvw

+0

Сценарий инициализации будет блокироваться до тех пор, пока он не завершит выполнение. Таким образом, сервер не будет работать до тех пор, пока это не завершится. Если вы хотите, чтобы этот скрипт постоянно работал в течение всего срока службы сервера (и избегайте блока), я полагаю, вам нужно будет запустить отдельный поток в вашем скрипте. Проблема заключается в том, как вы могли бы прекратить этот поток, так как не будет триггера, который будет знать, когда сервер закрывается. Я не против изменения сервера Gremlin, чтобы предоставить этот крючок как привязку, доступную из скрипта. См. Эту проблему: https: // github.com/tinkerpop/tinkerpop3/issues/553 –

+0

Хорошо, тогда я буду использовать клиентский подход. Спасибо за вашу помощь! – rvw