首页 > 代码库 > 企业搜索引擎开发之连接器connector(二十四)

企业搜索引擎开发之连接器connector(二十四)

本人在上文中提到,连接器实现了两种事件依赖的机制 ,其一是我们手动操作连接器实例时;其二是由连接器的自动更新机制

上文中分析了连接器的自动更新机制,即定时器执行定时任务

那么,如果我们手动操作连接器实例时,是怎么发出事件更新连接器实例的呢

通过eclipse开发工具,追踪调用ChangeDetector接口的detect()方法的方法

ChangeDetectorTask类的run方法里面调用我们再上文中已经分析了,其他方法便是ConnectorCoordinatorImpl实例对象的方法

即ConnectorCoordinatorImpl实例对象的如下方法,分别调用了ChangeDetector接口的detect()方法

/**
   * 移除连接器实例
   * Removes this {@link Connector} instance.  Halts traversals,
   * removes the Connector instance from the known connectors,
   * and removes the Connector‘s on-disk representation.
   */
  /* @Override */
  public void removeConnector() {
    synchronized(this) {
      resetBatch();
      if (instanceInfo != null) {
        instanceInfo.removeConnector();
      }
    }
    // This must not be called while holding the lock.
    changeDetector.detect();
  }

/**
   * 重启遍历
   * Retraverses the {@link Connector}‘s content from scratch.
   * Halts any traversal in progress and removes any saved traversal state,
   * forcing the Connector to retraverse the Repository from its start.
   */
  /* @Override */
  public void restartConnectorTraversal() throws ConnectorNotFoundException {
    // To avoid deadlock, this method calls InstanceInfo‘s getters and setters,
    // rather than the local ones.
    synchronized(this) {
      resetBatch();                               // Halt any traversal.
      getInstanceInfo().setConnectorState(null);  // Discard the checkpoint.

      // If Schedule was ‘run-once‘, re-enable it to run again.  But watch out -
      // empty disabled Schedules could look a bit like a run-once Schedule.
      Schedule schedule = getInstanceInfo().getConnectorSchedule();
      if (schedule != null && schedule.isDisabled() &&
            schedule.getRetryDelayMillis() == -1 &&
            schedule.nextScheduledInterval() != -1) {
          schedule.setDisabled(false);
          getInstanceInfo().setConnectorSchedule(schedule);
      }
    }

    // TODO: Remove this if we switch completely to JDBC PersistentStore.
    // FileStore doesn‘t notice the deletion of a file that did not exist.
    if (lister != null) {
      connectorCheckpointChanged(null);
    }

    // This must not be called while holding the lock.
    changeDetector.detect();
  }

/**
   * 设置配置信息
   * Sets the {@link Configuration} for this {@link ConnectorCoordinator}.
   * If this {@link ConnectorCoordinator} supports persistence this will
   * persist the new Configuration.
   */
  /* @Override */
  public ConfigureResponse setConnectorConfiguration(TypeInfo newTypeInfo,
      Configuration configuration, Locale locale, boolean update)
      throws ConnectorNotFoundException, ConnectorExistsException,
      InstantiatorException {
    LOGGER.info("Configuring connector " + name);
    String typeName = newTypeInfo.getConnectorTypeName();
    Preconditions.checkArgument(typeName.equals(configuration.getTypeName()),
        "TypeInfo must match Configuration type");
    ConfigureResponse response = null;
    synchronized(this) {
      resetBatch();
      if (instanceInfo != null) {
        if (!update) {
          throw new ConnectorExistsException();
        }
        if (typeName.equals(typeInfo.getConnectorTypeName())) {
          configuration =
              new Configuration(configuration, getConnectorConfiguration());
          response = resetConfig(instanceInfo.getConnectorDir(), typeInfo,
              configuration, locale);
        } else {
          // An existing connector is being given a new type - drop then add.
          // TODO: This shouldn‘t be called from within the synchronized block
          // because it will kick the change detector.
          removeConnector();
          response = createNewConnector(newTypeInfo, configuration, locale);
          if (response != null) {
            // TODO: We need to restore original Connector config. This is
            // necessary once we allow update a Connector with new ConnectorType.
            // However, when doing so consider: createNewConnector could have
            // thrown InstantiatorException as well.  Also, you need to kick
            // the changeDetector (but not in this synchronized block).
            LOGGER.severe("Failed to update Connector configuration.");
            //    + " Restoring original Connector configuration.");
          }
        }
      } else {
        if (update) {
          throw new ConnectorNotFoundException();
        }
        response = createNewConnector(newTypeInfo, configuration, locale);
      }
    }
    if (response == null) {
      // This must not be called while holding the lock.
      changeDetector.detect();
    } else {
      return new ExtendedConfigureResponse(response, configuration.getXml());
    }
    return response;
  }

/**
   * 设置定时调度
   * Sets the traversal {@link Schedule} for the {@link Connector}.
   *
   * @param connectorSchedule Schedule to store or null to unset any existing
   *        Schedule.
   * @throws ConnectorNotFoundException if the connector is not found
   */
  /* @Override */
  public void setConnectorSchedule(Schedule connectorSchedule)
      throws ConnectorNotFoundException {
    synchronized(this) {
      // Persistently store the new schedule.
      getInstanceInfo().setConnectorSchedule(connectorSchedule);
    }
    // This must not be called while holding the lock.
    changeDetector.detect();
  }

接下来ChangeDetector接口的detect()方法其实又调用了自身的实现ConnectorCoordinatorImpl实例对象的实现ChangeHandler接口的方法

ConnectorCoordinatorImpl-->ChangeDetector的detect()-->ChangeListener的相关方法-->ChangeHandler(ConnectorCoordinatorImpl实例对象)的相关方法

所以手动操作与自动更新机制实际上是殊途同归,最后都是调用了ChangeHandler(ConnectorCoordinatorImpl实例对象)的相关方法

---------------------------------------------------------------------------

本系列企业搜索引擎开发之连接器connector系本人原创

转载请注明出处 博客园 刺猬的温驯

本人邮箱: chenying998179@163#com (#改为.)

本文链接 http://www.cnblogs.com/chenying99/p/3776515.html