Search code examples
full-text-searchgremlincassandra-3.0janusgraphtinkerpop3

REGISTER_INDEX() Not Registering SchemaStatus.INSTALLED JanusGraph-Index


Why is JanusGraph not registering an installed-index?

The first time the janusGraphManagement.buildIndex() builds and enables fine.
Although, second time the janusGraphIndex will be stuck at INSTALLED and not auto-ENABLE.
REGISTER_INDEX never REGISTERED, no matter ManagementSystem.awaitGraphIndexStatus().

2023-05-16 13:12:50,052 [INFO] [Main.main] ::    SchemaAction.REGISTER_INDEX 
janusGraphIndex.getIndexStatus(propertyKey):    INSTALLED
...
2023-05-16 13:13:50,534 [INFO] [o.j.g.d.m.GraphIndexStatusWatcher.main] ::   Some key(s) on index _id do not currently have status(es) [REGISTERED]: _id=INSTALLED
2023-05-16 13:13:50,534 [INFO] [o.j.g.d.m.GraphIndexStatusWatcher.main] ::   Timed out (PT1M) while waiting for index _id to converge on status(es) [REGISTERED]
package org.janusgraph.core.schema;

// ...
public enum SchemaAction {
    REGISTER_INDEX(Collections.singleton(SchemaStatus.INSTALLED)),
    // ... 
}

JanusGraph worked the 1st-time and should be implicitly creating an index on these n-iterations.
"inmemory" has the same problem as seen in the ready sample I've provided.
After DROP_INDEX the same index id won't seem to work. Even when its gone and can't be found.

How are you supposed to rebuild indices on JanusGraph?

Logs

...
2023-05-16 14:00:17,702 [INFO] [Main.main] ::    SchemaAction.DISCARD_INDEX 
janusGraphIndex.getIndexStatus(propertyKey):    DISCARDED
2023-05-16 14:00:17,704 [INFO] [o.j.g.d.m.GraphIndexStatusWatcher.main] ::   All 1 key(s) on index _id have status(es) [DISCARDED]
2023-05-16 14:00:17,706 [INFO] [Main.main] ::    SchemaAction.DROP_INDEX 
janusGraphIndex.getIndexStatus(propertyKey):    DISCARDED
2023-05-16 14:00:17,810 [INFO] [Main.main] ::    SchemaAction.DROP_INDEX 
janusGraphIndex:    null
2023-05-16 14:00:17,821 [INFO] [Main.main] ::    buildCompositeIndex 
janusGraphIndex.getIndexStatus(propertyKey):    INSTALLED
2023-05-16 14:00:17,933 [INFO] [o.j.g.d.m.GraphIndexStatusWatcher.main] ::   All 1 key(s) on index _id have status(es) [INSTALLED]
2023-05-16 14:00:17,935 [INFO] [Main.main] ::    SchemaAction.DISCARD_INDEX 
janusGraphIndex.getIndexStatus(propertyKey):    INSTALLED
2023-05-16 14:00:18,056 [INFO] [o.j.g.d.m.GraphIndexStatusWatcher.main] ::   Some key(s) on index _id do not currently have status(es) [REGISTERED]: _id=INSTALLED
...
2023-05-16 14:00:26,765 [INFO] [o.j.g.d.m.GraphIndexStatusWatcher.main] ::   Some key(s) on index _id do not currently have status(es) [REGISTERED]: _id=INSTALLED
2023-05-16 14:00:27,217 [INFO] [o.j.g.d.m.ManagementLogger.pool-5-thread-1] ::   Received all acknowledgements for eviction [1]
2023-05-16 14:00:27,218 [INFO] [o.j.g.d.m.ManagementLogger.pool-5-thread-1] ::   Received all acknowledgements for eviction [2]
2023-05-16 14:00:27,219 [INFO] [o.j.g.d.m.ManagementLogger.pool-5-thread-1] ::   Received all acknowledgements for eviction [3]
2023-05-16 14:00:27,222 [INFO] [o.j.g.d.m.ManagementSystem$UpdateStatusTrigger.pool-5-thread-1] ::   Set status REGISTERED on schema element _id with property keys []
2023-05-16 14:00:27,281 [INFO] [o.j.g.d.m.GraphIndexStatusWatcher.main] ::   Some key(s) on index _id do not currently have status(es) [REGISTERED]: _id=INSTALLED
2023-05-16 14:00:27,327 [INFO] [o.j.g.d.m.ManagementLogger.pool-5-thread-1] ::   Received all acknowledgements for eviction [4]
2023-05-16 14:00:27,331 [INFO] [o.j.g.d.m.ManagementSystem$UpdateStatusTrigger.pool-5-thread-1] ::   Set status REGISTERED on schema element _id with property keys []
2023-05-16 14:00:27,435 [INFO] [o.j.g.d.m.ManagementLogger.pool-5-thread-1] ::   Received all acknowledgements for eviction [5]
2023-05-16 14:00:27,787 [INFO] [o.j.g.d.m.GraphIndexStatusWatcher.main] ::   All 1 key(s) on index _id have status(es) [REGISTERED]

Process finished with exit code 0

Code

        JanusGraph janusGraph = JanusGraphFactory.build().set("storage.backend", "inmemory").open();
//        JanusGraph janusGraph = JanusGraphFactory.build().set("storage.backend", "cql").set("storage.hostname", "localhost:9042").open();
        JanusGraphManagement janusGraphManagement = janusGraph.openManagement();
        PropertyKey propertyKey = janusGraphManagement.getOrCreatePropertyKey("_id");
        JanusGraphIndex janusGraphIndex;

        if (!janusGraphManagement.containsGraphIndex("_id")) {
//            janusGraphManagement = janusGraph.openManagement();
            janusGraphManagement.buildIndex("_id", Vertex.class).addKey(propertyKey).buildCompositeIndex();
            janusGraphIndex = janusGraphManagement.getGraphIndex("_id");
            logger.info("buildCompositeIndex \njanusGraphIndex.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
            janusGraphManagement.commit();
            ManagementSystem.awaitGraphIndexStatus(janusGraph, "_id").status(SchemaStatus.ENABLED).call();
        }

        janusGraphManagement = janusGraph.openManagement();
        janusGraphIndex = janusGraphManagement.getGraphIndex("_id");
        logger.info("index.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
        if (SchemaStatus.INSTALLED.equals(janusGraphIndex.getIndexStatus(propertyKey))) {
            janusGraphManagement.updateIndex(janusGraphIndex, SchemaAction.REGISTER_INDEX).get();
            logger.info("SchemaAction.REGISTER_INDEX \njanusGraphIndex.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
            janusGraphManagement.commit();
            ManagementSystem.awaitGraphIndexStatus(janusGraph, "_id").status(SchemaStatus.REGISTERED).call();
        }
        if (SchemaStatus.REGISTERED.equals(janusGraphIndex.getIndexStatus(propertyKey))) {
            janusGraphManagement = janusGraph.openManagement();
            janusGraphManagement.updateIndex(janusGraphIndex, SchemaAction.ENABLE_INDEX).get();
            logger.info("SchemaAction.ENABLE_INDEX \njanusGraphIndex.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
            janusGraphManagement.commit();
            ManagementSystem.awaitGraphIndexStatus(janusGraph, "_id").status(SchemaStatus.ENABLED).call();
        }
        if (SchemaStatus.ENABLED.equals(janusGraphIndex.getIndexStatus(propertyKey))) {
            janusGraphManagement.updateIndex(janusGraphIndex, SchemaAction.DISABLE_INDEX).get();
            logger.info("SchemaAction.DISABLE_INDEX \njanusGraphIndex.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
            janusGraphManagement.commit();
            ManagementSystem.awaitGraphIndexStatus(janusGraph, "_id").status(SchemaStatus.DISABLED).call();
        }
        if (SchemaStatus.DISABLED.equals((janusGraphIndex.getIndexStatus(propertyKey)))) {
            janusGraphManagement = janusGraph.openManagement();
            janusGraphIndex = janusGraphManagement.getGraphIndex("_id");
            janusGraphManagement.updateIndex(janusGraphIndex, SchemaAction.DISCARD_INDEX).get();
            logger.info("SchemaAction.DISCARD_INDEX \njanusGraphIndex.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
            janusGraphManagement.commit();
            ManagementSystem.awaitGraphIndexStatus(janusGraph, "_id").status(SchemaStatus.DISCARDED).call();
        }
        if (SchemaStatus.DISCARDED.equals((janusGraphIndex.getIndexStatus(propertyKey)))) {
            janusGraphManagement = janusGraph.openManagement();
            janusGraphIndex = janusGraphManagement.getGraphIndex("_id");
            janusGraphManagement.updateIndex(janusGraphIndex, SchemaAction.DROP_INDEX).get();
            logger.info("SchemaAction.DROP_INDEX \njanusGraphIndex.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
            janusGraphManagement.commit();
        }
        janusGraphManagement = janusGraph.openManagement();
        janusGraphIndex = janusGraphManagement.getGraphIndex("_id");
        logger.info("SchemaAction.DROP_INDEX \njanusGraphIndex:\t" + janusGraphIndex);
        propertyKey = janusGraphManagement.getOrCreatePropertyKey("_id");
        if (!janusGraphManagement.containsGraphIndex("_id")) {
            janusGraphManagement.buildIndex("_id", Vertex.class).addKey(propertyKey).buildCompositeIndex();
            janusGraphIndex = janusGraphManagement.getGraphIndex("_id");
            logger.info("buildCompositeIndex \njanusGraphIndex.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
            janusGraphManagement.commit();
            ManagementSystem.awaitGraphIndexStatus(janusGraph, "_id").status(SchemaStatus.INSTALLED).call();
        }
        if (SchemaStatus.INSTALLED.equals((janusGraphIndex.getIndexStatus(propertyKey)))) {
            janusGraphManagement = janusGraph.openManagement();
            janusGraphIndex = janusGraphManagement.getGraphIndex("_id");
            janusGraphManagement.updateIndex(janusGraphIndex, SchemaAction.REGISTER_INDEX).get();
            logger.info("SchemaAction.DISCARD_INDEX \njanusGraphIndex.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
            janusGraphManagement.commit();
            ManagementSystem.awaitGraphIndexStatus(janusGraph, "_id").status(SchemaStatus.REGISTERED).call();
        }
        if (SchemaStatus.REGISTERED.equals((janusGraphIndex.getIndexStatus(propertyKey)))) {
            janusGraphManagement = janusGraph.openManagement();
            janusGraphIndex = janusGraphManagement.getGraphIndex("_id");
            janusGraphManagement.updateIndex(janusGraphIndex, SchemaAction.ENABLE_INDEX).get();
            logger.info("SchemaAction.DISCARD_INDEX \njanusGraphIndex.getIndexStatus(propertyKey):\t" + janusGraphIndex.getIndexStatus(propertyKey));
            janusGraphManagement.commit();
            ManagementSystem.awaitGraphIndexStatus(janusGraph, "_id").status(SchemaStatus.ENABLED).call();
        }

Reproduction

  1. Maven 3.8.1
  2. Java 17.0.7
  3. JanusGraph 1.0.0-20230504-014643.988c094
  4. Windows
  5. Docker
  6. Cassandra:latest [container]
  7. Harvard's Lung Cancer Dataset

Solution

  • When working with transactions, it is important not to mix them up. Objects received from one transaction may cause unexpected behavior when supplied to other transactions. Therefore, it is a good practice to fetch indexes and property keys when needed, instead of storing them across multiple transactions.

    Another thing to keep in mind is that indexes should not be modified while other management transactions are open simultaneously. Putting all of that together, I was able to make your example work:

    //Never create new indexes while a transaction is active
    graph.getOpenTransactions().forEach(JanusGraphTransaction::rollback);
    mgmt = graph.openManagement();
    
    mgmt.getOrCreatePropertyKey("_id");
    if (!mgmt.containsGraphIndex("_id")) {
        mgmt.buildIndex("_id", Vertex.class).addKey(mgmt.getPropertyKey("_id")).buildCompositeIndex();
        mgmt.commit();
        ManagementSystem.awaitGraphIndexStatus(graph, "_id").status(SchemaStatus.ENABLED).call();
        mgmt = graph.openManagement();
    }
    if (SchemaStatus.INSTALLED.equals(mgmt.getGraphIndex("_id").getIndexStatus(mgmt.getPropertyKey("_id")))) {
        mgmt.updateIndex(mgmt.getGraphIndex("_id"), SchemaAction.REGISTER_INDEX).get();
        mgmt.commit();
        ManagementSystem.awaitGraphIndexStatus(graph, "_id").status(SchemaStatus.REGISTERED).call();
        mgmt = graph.openManagement();
    }
    if (SchemaStatus.REGISTERED.equals(mgmt.getGraphIndex("_id").getIndexStatus(mgmt.getPropertyKey("_id")))) {
        mgmt.updateIndex(mgmt.getGraphIndex("_id"), SchemaAction.ENABLE_INDEX).get();
        mgmt.commit();
        ManagementSystem.awaitGraphIndexStatus(graph, "_id").status(SchemaStatus.ENABLED).call();
        mgmt = graph.openManagement();
    }
    if (SchemaStatus.ENABLED.equals(mgmt.getGraphIndex("_id").getIndexStatus(mgmt.getPropertyKey("_id")))) {
        mgmt.updateIndex(mgmt.getGraphIndex("_id"), SchemaAction.DISABLE_INDEX).get();
        mgmt.commit();
        ManagementSystem.awaitGraphIndexStatus(graph, "_id").status(SchemaStatus.DISABLED).call();
        mgmt = graph.openManagement();
    }
    if (SchemaStatus.DISABLED.equals(mgmt.getGraphIndex("_id").getIndexStatus(mgmt.getPropertyKey("_id")))) {
        mgmt.updateIndex(mgmt.getGraphIndex("_id"), SchemaAction.DISCARD_INDEX).get();
        mgmt.commit();
        ManagementSystem.awaitGraphIndexStatus(graph, "_id").status(SchemaStatus.DISCARDED).call();
        mgmt = graph.openManagement();
    }
    if (SchemaStatus.DISCARDED.equals(mgmt.getGraphIndex("_id").getIndexStatus(mgmt.getPropertyKey("_id")))) {
        mgmt.updateIndex(mgmt.getGraphIndex("_id"), SchemaAction.DROP_INDEX).get();
        mgmt.commit();
        mgmt = graph.openManagement();
    }
    
    if (!mgmt.containsGraphIndex("_id")) {
        mgmt.buildIndex("_id", Vertex.class).addKey(mgmt.getPropertyKey("_id")).buildCompositeIndex();
        mgmt.commit();
        ManagementSystem.awaitGraphIndexStatus(graph, "_id").status(SchemaStatus.REGISTERED).call();
        mgmt = graph.openManagement();
    }
    if (SchemaStatus.REGISTERED.equals(mgmt.getGraphIndex("_id").getIndexStatus(mgmt.getPropertyKey("_id")))) {
        mgmt.updateIndex(mgmt.getGraphIndex("_id"), SchemaAction.ENABLE_INDEX).get();
        mgmt.commit();
        ManagementSystem.awaitGraphIndexStatus(graph, "_id").status(SchemaStatus.ENABLED).call();
    }