// Copyright 2017 JanusGraph Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package org.janusgraph.graphdb.database.management; import com.google.common.base.Preconditions; import org.janusgraph.core.JanusGraph; import org.janusgraph.core.schema.RelationTypeIndex; import org.janusgraph.core.schema.SchemaStatus; import org.janusgraph.core.schema.JanusGraphManagement; import org.janusgraph.diskstorage.util.time.Timer; import org.janusgraph.diskstorage.util.time.TimestampProviders; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class RelationIndexStatusWatcher extends AbstractIndexStatusWatcher<RelationIndexStatusReport, RelationIndexStatusWatcher> { private static final Logger LOGGER = LoggerFactory.getLogger(RelationIndexStatusWatcher.class); private String relationIndexName; private String relationTypeName; public RelationIndexStatusWatcher(JanusGraph g, String relationIndexName, String relationTypeName) { super(g); this.relationIndexName = relationIndexName; this.relationTypeName = relationTypeName; } @Override protected RelationIndexStatusWatcher self() { return this; } /** * Poll a relation index until it has a certain {@link SchemaStatus}, * or until a configurable timeout is exceeded. * * @return a report with information about schema state, execution duration, and the index */ @Override public RelationIndexStatusReport call() throws InterruptedException { Preconditions.checkNotNull(g, "Graph instance must not be null"); Preconditions.checkNotNull(relationIndexName, "Index name must not be null"); Preconditions.checkNotNull(statuses, "Target statuses must not be null"); Preconditions.checkArgument(statuses.size() > 0, "Target statuses must include at least one status"); RelationTypeIndex idx; Timer t = new Timer(TimestampProviders.MILLI).start(); boolean timedOut; while (true) { SchemaStatus actualStatus = null; JanusGraphManagement mgmt = null; try { mgmt = g.openManagement(); idx = mgmt.getRelationIndex(mgmt.getRelationType(relationTypeName), relationIndexName); actualStatus = idx.getIndexStatus(); LOGGER.info("Index {} (relation type {}) has status {}", relationIndexName, relationTypeName, actualStatus); if (statuses.contains(actualStatus)) { return new RelationIndexStatusReport(true, relationIndexName, relationTypeName, actualStatus, statuses, t.elapsed()); } } finally { if (null != mgmt) mgmt.rollback(); // Let an exception here propagate up the stack } timedOut = null != timeout && 0 < t.elapsed().compareTo(timeout); if (timedOut) { LOGGER.info("Timed out ({}) while waiting for index {} (relation type {}) to reach status(es) {}", timeout, relationIndexName, relationTypeName, statuses); return new RelationIndexStatusReport(false, relationIndexName, relationTypeName, actualStatus, statuses, t.elapsed()); } Thread.sleep(poll.toMillis()); } } }