All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.orientechnologies.orient.server.OPushManager Maven / Gradle / Ivy

There is a newer version: 3.2.35
Show newest version
package com.orientechnologies.orient.server;

import com.orientechnologies.common.log.OLogManager;
import com.orientechnologies.common.thread.OThreadPoolExecutors;
import com.orientechnologies.orient.client.remote.message.OBinaryPushRequest;
import com.orientechnologies.orient.client.remote.message.OBinaryPushResponse;
import com.orientechnologies.orient.client.remote.message.OPushDistributedConfigurationRequest;
import com.orientechnologies.orient.client.remote.message.OPushFunctionsRequest;
import com.orientechnologies.orient.client.remote.message.OPushIndexManagerRequest;
import com.orientechnologies.orient.client.remote.message.OPushSchemaRequest;
import com.orientechnologies.orient.client.remote.message.OPushSequencesRequest;
import com.orientechnologies.orient.client.remote.message.OPushStorageConfigurationRequest;
import com.orientechnologies.orient.core.config.OStorageConfiguration;
import com.orientechnologies.orient.core.db.ODatabaseDocumentInternal;
import com.orientechnologies.orient.core.db.OMetadataUpdateListener;
import com.orientechnologies.orient.core.index.OIndexManagerAbstract;
import com.orientechnologies.orient.core.index.OIndexManagerShared;
import com.orientechnologies.orient.core.metadata.schema.OSchemaShared;
import com.orientechnologies.orient.server.network.protocol.binary.ONetworkProtocolBinary;
import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.RejectedExecutionException;

public class OPushManager implements OMetadataUpdateListener {

  protected final Set> distributedConfigPush =
      new HashSet<>();
  protected final OPushEventType storageConfigurations = new OPushEventType();
  protected final OPushEventType schema = new OPushEventType();
  protected final OPushEventType indexManager = new OPushEventType();
  protected final OPushEventType functions = new OPushEventType();
  protected final OPushEventType sequences = new OPushEventType();
  private Set registerDatabase = new HashSet<>();
  private final ExecutorService executor;

  public OPushManager() {
    executor =
        OThreadPoolExecutors.newCachedThreadPool(
            "Push Requests", Thread.currentThread().getThreadGroup(), 5, 0);
  }

  public synchronized void pushDistributedConfig(String database, List hosts) {
    Iterator> iter = distributedConfigPush.iterator();
    while (iter.hasNext()) {
      WeakReference ref = iter.next();
      ONetworkProtocolBinary protocolBinary = ref.get();
      if (protocolBinary != null) {
        // TODO Filter by database, push just list of active server for a specific database
        OPushDistributedConfigurationRequest request =
            new OPushDistributedConfigurationRequest(hosts);
        try {
          OBinaryPushResponse response = protocolBinary.push(request);
        } catch (IOException e) {
          iter.remove();
        }
      } else {
        iter.remove();
      }
    }
  }

  public synchronized void subscribeDistributeConfig(ONetworkProtocolBinary channel) {
    distributedConfigPush.add(new WeakReference(channel));
  }

  public synchronized void cleanPushSockets() {
    Iterator> iter = distributedConfigPush.iterator();
    while (iter.hasNext()) {
      if (iter.next().get() == null) {
        iter.remove();
      }
    }
    storageConfigurations.cleanListeners();
    schema.cleanListeners();
    indexManager.cleanListeners();
    functions.cleanListeners();
    sequences.cleanListeners();
  }

  private void cleanListeners(Map>> toClean) {
    for (Set> value : toClean.values()) {
      Iterator> iter = value.iterator();
      while (iter.hasNext()) {
        if (iter.next().get() == null) {
          iter.remove();
        }
      }
    }
  }

  public void shutdown() {
    executor.shutdownNow();
  }

  private void genericSubscribe(
      OPushEventType context, ODatabaseDocumentInternal database, ONetworkProtocolBinary protocol) {
    if (!registerDatabase.contains(database.getName())) {
      database.getSharedContext().registerListener(this);
      registerDatabase.add(database.getName());
    }
    context.subscribe(database.getName(), protocol);
  }

  public synchronized void subscribeStorageConfiguration(
      ODatabaseDocumentInternal database, ONetworkProtocolBinary protocol) {
    genericSubscribe(storageConfigurations, database, protocol);
  }

  public synchronized void subscribeSchema(
      ODatabaseDocumentInternal database, ONetworkProtocolBinary protocol) {
    genericSubscribe(schema, database, protocol);
  }

  public synchronized void subscribeIndexManager(
      ODatabaseDocumentInternal database, ONetworkProtocolBinary protocol) {
    genericSubscribe(indexManager, database, protocol);
  }

  public synchronized void subscribeFunctions(
      ODatabaseDocumentInternal database, ONetworkProtocolBinary protocol) {
    genericSubscribe(functions, database, protocol);
  }

  public synchronized void subscribeSequences(
      ODatabaseDocumentInternal database, ONetworkProtocolBinary protocol) {
    genericSubscribe(sequences, database, protocol);
  }

  @Override
  public void onSchemaUpdate(String database, OSchemaShared schema) {
    OPushSchemaRequest request = new OPushSchemaRequest(schema.toNetworkStream());
    this.schema.send(database, request, this);
  }

  @Override
  public void onIndexManagerUpdate(String database, OIndexManagerAbstract indexManager) {
    OPushIndexManagerRequest request =
        new OPushIndexManagerRequest(((OIndexManagerShared) indexManager).toNetworkStream());
    this.indexManager.send(database, request, this);
  }

  @Override
  public void onFunctionLibraryUpdate(String database) {
    OPushFunctionsRequest request = new OPushFunctionsRequest();
    this.functions.send(database, request, this);
  }

  @Override
  public void onSequenceLibraryUpdate(String database) {
    OPushSequencesRequest request = new OPushSequencesRequest();
    this.sequences.send(database, request, this);
  }

  @Override
  public void onStorageConfigurationUpdate(String database, OStorageConfiguration update) {
    OPushStorageConfigurationRequest request = new OPushStorageConfigurationRequest(update);
    storageConfigurations.send(database, request, this);
  }

  public void genericNotify(
      Map>> context,
      String database,
      OPushEventType pack) {
    try {
      executor.submit(
          () -> {
            Set> clients = null;
            synchronized (OPushManager.this) {
              Set> cl = context.get(database);
              if (cl != null) {
                clients = new HashSet<>(cl);
              }
            }
            if (clients != null) {
              Iterator> iter = clients.iterator();
              while (iter.hasNext()) {
                WeakReference ref = iter.next();
                ONetworkProtocolBinary protocolBinary = ref.get();
                if (protocolBinary != null) {
                  try {
                    OBinaryPushRequest request = pack.getRequest(database);
                    if (request != null) {
                      OBinaryPushResponse response = protocolBinary.push(request);
                    }
                  } catch (IOException e) {
                    synchronized (OPushManager.this) {
                      context.get(database).remove(ref);
                    }
                  }
                } else {
                  synchronized (OPushManager.this) {
                    context.get(database).remove(ref);
                  }
                }
              }
            }
          });
    } catch (RejectedExecutionException e) {
      OLogManager.instance()
          .info(this, "Cannot send push request to client for database '%s'", database);
    }
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy