Package be.bagofwords.db.remote

Source Code of be.bagofwords.db.remote.RemoteDatabaseInterfaceFactory

package be.bagofwords.db.remote;

import be.bagofwords.application.memory.MemoryManager;
import be.bagofwords.cache.CachesManager;
import be.bagofwords.db.DataInterface;
import be.bagofwords.db.DataInterfaceFactory;
import be.bagofwords.db.application.environment.RemoteCountDBEnvironmentProperties;
import be.bagofwords.db.combinator.Combinator;
import be.bagofwords.ui.UI;
import be.bagofwords.util.SafeThread;
import be.bagofwords.util.WrappedSocketConnection;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.io.IOException;
import java.net.SocketException;
import java.util.HashMap;
import java.util.Map;

import static be.bagofwords.application.BaseServer.LONG_OK;

public class RemoteDatabaseInterfaceFactory extends DataInterfaceFactory {

    private final String host;
    private final int port;
    private Map<String, DataInterface> dataInterfaceMap;
    private ChangedValueListenerThread changedValueListenerThread;

    @Autowired
    public RemoteDatabaseInterfaceFactory(CachesManager cachesManager, MemoryManager memoryManager, RemoteCountDBEnvironmentProperties environmentProperties) {
        this(cachesManager, memoryManager, environmentProperties.getDatabaseServerAddress(), environmentProperties.getDataInterfaceServerPort());
    }

    public RemoteDatabaseInterfaceFactory(CachesManager cachesManager, MemoryManager memoryManager, String host, int port) {
        super(cachesManager, memoryManager);
        this.host = host;
        this.port = port;
        this.dataInterfaceMap = new HashMap<>();
    }

    @Override
    protected synchronized <T extends Object> DataInterface<T> createBaseDataInterface(String nameOfSubset, Class<T> objectClass, Combinator<T> combinator) {
        if (changedValueListenerThread == null) {
            synchronized (this) {
                try {
                    this.changedValueListenerThread = new ChangedValueListenerThread();
                    this.changedValueListenerThread.start();
                } catch (IOException e) {
                    throw new RuntimeException("Unexpected exception while starting changedValueListenerThread", e);
                }
            }
        }
        DataInterface result = new RemoteDataInterface<>(nameOfSubset, objectClass, combinator, host, port);
        dataInterfaceMap.put(nameOfSubset, result);
        return result;
    }

    @Override
    public synchronized void close() {
        if (changedValueListenerThread != null) {
            changedValueListenerThread.terminateAndWait();
        }
        super.close();
    }

    private class ChangedValueListenerThread extends SafeThread {

        private WrappedSocketConnection connection;

        public ChangedValueListenerThread() throws IOException {
            super("ChangedValueListener", false);
            connection = new WrappedSocketConnection(host, port);
        }

        @Override
        protected void runInt() throws Exception {
            connection.writeByte((byte) RemoteDataInterfaceServer.Action.LISTEN_TO_CHANGES.ordinal());
            connection.flush();
            try {
                while (!isTerminateRequested()) {
                    String interfaceName = connection.readString();
                    int numOfKeys = connection.readInt();
                    long[] keys = new long[numOfKeys];
                    for (int i = 0; i < numOfKeys; i++) {
                        keys[i] = connection.readLong();
                    }
                    DataInterface dataInterface = dataInterfaceMap.get(interfaceName);
                    if (dataInterface != null) {
                        dataInterface.notifyListenersOfChangedValues(keys);
                    }
                    connection.writeLong(LONG_OK);
                    connection.flush();
                }
            } catch (SocketException exp) {
                if (!exp.getMessage().equals("Socket closed")) {
                    UI.writeError("Error in ChangedValueListener", exp);
                }
            }
            IOUtils.closeQuietly(connection);
        }

        @Override
        protected void doTerminate() {
            IOUtils.closeQuietly(connection);
        }
    }
}
TOP

Related Classes of be.bagofwords.db.remote.RemoteDatabaseInterfaceFactory

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.