Package com.mobixess.jodb.core

Source Code of com.mobixess.jodb.core.JODBServer$RemoteTransactionContainer$UnlockTransactionRunnable

/*
Copyright (C) 2007  Mobixess Inc. http://www.java-objects-database.com

This file is part of the JODB (Java Objects Database) open source project.

JODB is free software; you can redistribute it and/or modify it under
the terms of version 2 of the GNU General Public License as published
by the Free Software Foundation.

JODB is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
package com.mobixess.jodb.core;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.URI;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.spi.SelectorProvider;
import java.rmi.Naming;
import java.rmi.NotBoundException;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.Comparator;
import java.util.HashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.Semaphore;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Level;

import com.mobixess.jodb.core.index.JODBIndexingRootAgent;
import com.mobixess.jodb.core.io.IOTicket;
import com.mobixess.jodb.core.io.IRandomAccessDataBuffer;
import com.mobixess.jodb.core.io.JODBIOBase;
import com.mobixess.jodb.core.io.IOBase.ObjectIdentity;
import com.mobixess.jodb.core.io.IRandomAccessBufferFactory.BUFFER_TYPE;
import com.mobixess.jodb.core.io.rmi.IDatabaseStatisticsRemote;
import com.mobixess.jodb.core.io.rmi.IOTicketRemoteInterface;
import com.mobixess.jodb.core.io.rmi.IRemoteServer;
import com.mobixess.jodb.core.io.rmi.IRemoteTransactionContainer;
import com.mobixess.jodb.core.io.rmi.IRemoteServer.IServerQueryResult;
import com.mobixess.jodb.core.query.JODBQueryList;
import com.mobixess.jodb.core.query.NQExecutor;
import com.mobixess.jodb.core.query.QueryNode;
import com.mobixess.jodb.core.transaction.ITranslatedDataSorce;
import com.mobixess.jodb.core.transaction.JODBSession;
import com.mobixess.jodb.core.transaction.TransactionContainer;
import com.mobixess.jodb.core.transaction.TransactionUtils;
import com.mobixess.jodb.core.transaction.JODBSession.ClassDescriptor;
import com.mobixess.jodb.query.api.Predicate;
import com.mobixess.jodb.util.LongVector;
import com.mobixess.jodb.util.Utils;
import com.mobixess.jodb.util.rmi.RegistryManager;


public class JODBServer {
   
    private JODBSessionContainer _sessionContainer;
    private JODBIOBase _ioBase;
    private String _serverId;
    private ServerSocketAcceptor _serverSocketAcceptor;
    private JODBRemoteObject _remoteObject;
    //private int _rmiPort;
    //private int _dataPort;
    public final static String REMOTE_OBJECT_NAME = '/'+JODBRemoteObject.class.getName();
    private JODBIndexingRootAgent _indexingRootAgent;
   
    JODBServer(JODBSessionContainer sessionContainer, String serverId) throws Exception {
        _sessionContainer = sessionContainer;
        _ioBase = (JODBIOBase) _sessionContainer.getIoBase();
        _serverId = serverId;
        _serverSocketAcceptor = new ServerSocketAcceptor();
        installServerObject();
        reloadIndexingRootAgent();
    }
   
    private void installServerObject() throws Exception{
        RegistryManager.getInstance().createRegistry();
        String name = composeRemoteObjectBindName();
        Naming.rebind(name, _remoteObject = new JODBRemoteObject());
    }
   
    private String composeRemoteObjectBindName(){
        String name = REMOTE_OBJECT_NAME;
        if(_serverId!=null && _serverId.length()>0){
            name+="_"+_serverId;
        }
        return name;
    }
   
    public synchronized void stop() throws IOException{
        _sessionContainer.close();
        _serverSocketAcceptor.close();
        try {
            Naming.unbind(composeRemoteObjectBindName());
            UnicastRemoteObject.unexportObject(_remoteObject, true);
        } catch (NotBoundException e) {
            throw new JodbIOException(e);
        } finally{
            RegistryManager.getInstance().shutdownRegistry();
        }
    }
   
    private void reloadIndexingRootAgent() throws IOException{
        JODBSession session = _sessionContainer.getSession();
        long offset = session.getIndexingRootAgentOffset();
        _indexingRootAgent = (JODBIndexingRootAgent) TransactionUtils.launchObject(session, offset, _indexingRootAgent, Integer.MAX_VALUE);
    }
   
   
   
    @SuppressWarnings("serial")
    private class JODBRemoteObject extends UnicastRemoteObject implements IRemoteServer{

        DatabaseStatisticsSE _databaseStatisticsSE;
       
        protected JODBRemoteObject() throws IOException {
            super();
            _databaseStatisticsSE = new DatabaseStatisticsSE();
        }

        public void applyTransaction(TransactionContainer transactionContainer, JODBSession session, IOTicket writeTicket, JODBIndexingRootAgent indexingRootAgent) throws IOException {
           
        }

        public void close() throws IOException, RemoteException {
            _sessionContainer.close();
        }

        public String getClassTypeForID(int id) {
            return _ioBase.getClassTypeForID(id);
        }

        public int getClassTypeSubstitutionID(String classType) throws RemoteException {
            return _ioBase.getClassTypeSubstitutionID(classType);
        }

        public IDatabaseStatisticsRemote getDatabaseStatistics() throws IOException {
            if(!_databaseStatisticsSE.isExported()){
                _databaseStatisticsSE.export();
            }
            _databaseStatisticsSE.setDatabaseStatistics(_ioBase.getDatabaseStatistics(true));
            return _databaseStatisticsSE;
        }

        public URI getDbIdentificator() {
            return _ioBase.getDbIdentificator();
        }

        public long getFirstObjectOffset() throws RemoteException {
            return _ioBase.getFirstObjectOffset();
        }

        public long[] getForAllObjects(int ioTicket) throws IOException {
            IOTicket ticket = _ioBase.findTicket(ioTicket);
            return _ioBase.getForAllObjects(ticket);
        }

        public String getFullFieldNameForID(int id) throws RemoteException {
            return _ioBase.getFullFieldNameForID(id);
        }

        public IOTicketRemoteInterface getIOTicket(boolean read, boolean write) throws IOException {
            try {
                return (IOTicketRemoteInterface) _ioBase.getIOTicket(read, write, true);
            } catch (IOException e) {
                e.printStackTrace();
                throw e;
            }           
        }

        public int getOrSetClassTypeSubstitutionID(Class clazz) throws RemoteException {
            return _ioBase.getOrSetClassTypeSubstitutionID(clazz);
        }

        public int getOrSetClassTypeSubstitutionID(String classType) throws RemoteException {
            return _ioBase.getOrSetClassTypeSubstitutionID(classType);
        }

//        public int getOrSetFieldSubstitutionID(Field field) throws RemoteException {
//            return _ioBase.getOrSetFieldSubstitutionID(field);
//        }

        public IPersistentObjectStatistics getPersistenceStatistics(long offset, JODBSession session) throws IOException {
            return _ioBase.getPersistenceStatistics(offset, session);
        }

        public String getPrefixForID(int id) {
            return _ioBase.getPrefixForID(id);
        }

        public String getSimpleFieldNameForID(int id) throws RemoteException {
            return _ioBase.getSimpleFieldNameForID(id);
        }

        public boolean isClosed() throws RemoteException {
            return _ioBase.isClosed();
        }

        public IRemoteTransactionContainer getRemoteTransactionContainer() throws RemoteException {
            try {
                return new RemoteTransactionContainer();
            } catch (IOException e) {
                throw new RemoteException("",e);
            }
        }

        public IServerQueryResult runQuery(QueryNode query, long[] localActiveObjects) throws IOException{
            LongVector remoteActiveObjects=null;
            if(localActiveObjects!=null){
                remoteActiveObjects = new LongVector(localActiveObjects);
            }
            query.setSession(_sessionContainer.getSession());
            try {
                LongVector additionalRejected = new LongVector();
                JODBQueryList objectSet = (JODBQueryList) query.runQuery(remoteActiveObjects,additionalRejected);
               
                long[] result = objectSet.getAllObjectIds();
                long[] additionalRejectedObjects = null;
                if(additionalRejected.size() > 0){
                    additionalRejectedObjects = additionalRejected.getDataAsArray();
                }
                return new ServerQueryResult(additionalRejectedObjects,result);
            } catch (IllegalClassTypeException e) {
                throw new JodbIOException(e);
            }
        }

        public int getOrSetFieldSubstitutionID(int declaringClassID, int fieldTypeID, String fieldName) throws IOException {
            return _ioBase.getOrSetFieldSubstitutionID(declaringClassID, fieldTypeID, fieldName);
        }
       
        public int getFieldSubstitutionID(int declaringClassID, int fieldTypeID, String fieldName) throws IOException {
            return _ioBase.getFieldSubstitutionID(declaringClassID, fieldTypeID, fieldName);
        }

        public IPersistentObjectStatistics getPersistenceStatistics(long offset) throws IOException {
            return _ioBase.getPersistenceStatistics(offset, _sessionContainer.getSession());
        }

        public ObjectIdentity checkObjectChanged(long objectId, int hash, byte versionCounter) throws IOException {
            return _ioBase.checkObjectChanged(objectId, hash, versionCounter);
        }
       
        @SuppressWarnings("unchecked")
        public boolean isOptimizedQuery( String predicateClassName, String comparatorClassName)throws IOException
        {
            JODBSession session = _sessionContainer.getSession();
            Predicate predicate;
            Comparator comparator = null;
            try {
                ClassDescriptor predicateClassDescriptor = session.getDescriptorForClass(predicateClassName);
                predicate = (Predicate) predicateClassDescriptor.newInstance();
                if (comparatorClassName != null) {
                    ClassDescriptor comparatorClassDescriptor = session.getDescriptorForClass(comparatorClassName);
                    comparator = (Comparator) comparatorClassDescriptor.newInstance();
                }
            } catch (Exception e) {
                throw new JodbIOException(e);
            }
            return NQExecutor.getInstance().isOptimizedQuery(_sessionContainer.getSession(), predicate, comparator);
        }

        @SuppressWarnings("unchecked")
        public IServerQueryResult query( String predicateClassName, String comparatorClassName)throws IOException
        {
            JODBSession session = _sessionContainer.getSession();
            Predicate predicate;
            Comparator comparator = null;
            try {
                ClassDescriptor predicateClassDescriptor = session.getDescriptorForClass(predicateClassName);
                predicate = (Predicate) predicateClassDescriptor.newInstance();
                if (comparatorClassName != null) {
                    ClassDescriptor comparatorClassDescriptor = session.getDescriptorForClass(comparatorClassName);
                    comparator = (Comparator) comparatorClassDescriptor.newInstance();
                }
            } catch (Exception e) {
                throw new JodbIOException(e);
            }
            JODBQueryList objectSet =  (JODBQueryList) NQExecutor.getInstance().execute(_sessionContainer.getSession(), predicate, comparator);
            long[] result = objectSet.getAllObjectIds();
            return new ServerQueryResult(null,result);
        }

    }
   
    private static class ServerQueryResult implements IServerQueryResult, Serializable{
       
        /**
         *
         */
        private static final long serialVersionUID = 1L;
       
        long[] _excludedObjects;
        long[] _searchResult;

        /**
         * @param excludedObjects
         * @param searchResult
         */
        public ServerQueryResult(long[] excludedObjects, long[] searchResult) {
            super();
            _excludedObjects = excludedObjects;
            _searchResult = searchResult;
        }

        public long[] getExcludedObjects() {
            return _excludedObjects;
        }

        public long[] getSearchResult() {
            return _searchResult;
        }
       
    }
   
    private class RemoteTransactionContainer implements IRemoteTransactionContainer, ITranslatedDataSorce{
        private FileReceiver _newDataBuffer;
        private FileReceiver _replacementsBuffer;
        private FileReceiver _rollbackBuffer;

        ReentrantReadWriteLock _lock;
        long _transactionOffset;
        ExecutorService _localTransactionExecutor = Executors.newSingleThreadExecutor();
        Future _transactionFuture;
        Exception _transactionExecutionError;
        LockTransuctionRunnable _lockTransuctionRunnable = new LockTransuctionRunnable();
        CompleteTransactionRunnable _completeTransactionRunnable = new CompleteTransactionRunnable();
        UnlockTransactionRunnable _unlockTransactionRunnable = new UnlockTransactionRunnable();
       
       
       
        public RemoteTransactionContainer() throws IOException {
            _lock = _ioBase.getTransactionLock();
            _newDataBuffer = new FileReceiver(BUFFER_TYPE.NEW_DATA);
            _replacementsBuffer = new FileReceiver(BUFFER_TYPE.REPLACEMENTS);
            _rollbackBuffer = new FileReceiver(BUFFER_TYPE.ROLLBACK);
            UnicastRemoteObject.exportObject(this, JodbNetConstants.DEFAULT_RMI_PORT);
        }
       
        public int getNewDataBufferId() {
            return _newDataBuffer.getFileId();
        }
       
        public int getReplacementsBufferId() {
            return _replacementsBuffer.getFileId();
        }
       
        public long getIndexingAgentVersion() throws IOException{
            return _indexingRootAgent.getVersion();
        }
       
       
       
        public int getRollbackBufferId() {
            return _rollbackBuffer.getFileId();
        }
       
        public FileReceiver getReceiverForId(int id){
            if(_newDataBuffer.getFileId() == id){
                return _newDataBuffer;
            }
            if(_replacementsBuffer.getFileId() == id){
                return _replacementsBuffer;
            }
            if(_rollbackBuffer.getFileId() == id){
                return _rollbackBuffer;
            }
            return null;
        }
       
        boolean hasPendingFiles(){
            return !_newDataBuffer._processed || !_replacementsBuffer._processed || !_rollbackBuffer._processed;
        }
       
        void ensureFileTransferComplete() throws IOException{
            ensureFileTransferComplete(JodbNetConstants.FILE_TRANSFER_MAX_WAIT, _newDataBuffer);
            ensureFileTransferComplete(JodbNetConstants.FILE_TRANSFER_MAX_WAIT, _replacementsBuffer);
            ensureFileTransferComplete(JodbNetConstants.FILE_TRANSFER_MAX_WAIT, _rollbackBuffer);
        }
       
       
        void ensureFileTransferComplete(int timeout, FileReceiver fileReceiver) throws IOException{
            if(fileReceiver._error!=null){
                throw new JodbIOException(fileReceiver._error);
            }

            try {
                fileReceiver.getTransferCompletionSynch(timeout).get(timeout, TimeUnit.MILLISECONDS);
            } catch (Exception e) {
                throw new JodbIOException(e);
            }
            if(fileReceiver._error!=null){
                throw new JodbIOException(fileReceiver._error);
            }
            if(!fileReceiver._transferComplete){
                throw new JodbIOException("Transfer timeout");
            }
        }

        public IRandomAccessDataBuffer getRollbackDataFile() {
            return _rollbackBuffer._file;
        }

        public IRandomAccessDataBuffer getTransactionNewDataFile() {
            return _newDataBuffer._file;
        }

        public IRandomAccessDataBuffer getTransactionReplacementsDataFile() {
            return _replacementsBuffer._file;
        }

        public void resetTransactionBufferToEnd() throws IOException {
            getRollbackDataFile().resetToEnd();
            getTransactionNewDataFile().resetToEnd();
            getTransactionReplacementsDataFile().resetToEnd();
        }

        public void resetTransactionBufferToStart() throws IOException {
            getRollbackDataFile().resetToStart();
            getTransactionNewDataFile().resetToStart();
            getTransactionReplacementsDataFile().resetToStart();
        }

        public void resetTranslatedObjects(JODBSession session, long transactionShift) {
            _lock.writeLock().unlock();
        }
       
        public long initTransaction() throws RemoteException {
            return initTransaction(JodbNetConstants.DEFAULT_TRANSACTION_LOCK_WAIT_TIMEOUT);
        }

        public long initTransaction(int transactioLockTimeout) throws RemoteException {
            Future future = _localTransactionExecutor.submit(_lockTransuctionRunnable);
            try {
                future.get(transactioLockTimeout, TimeUnit.MILLISECONDS);
            } catch (Exception e) {
                throw new RemoteException("",e);
            }
            if(!_lockTransuctionRunnable._gotLock){
                throw new RemoteException("Unable to obtain transaction lock");
            }

            _serverSocketAcceptor.addReciever(_newDataBuffer);
            _serverSocketAcceptor.addReciever(_replacementsBuffer);
            _serverSocketAcceptor.addReciever(_rollbackBuffer);

            _transactionOffset = _ioBase.getTransactionOffset();
            _transactionFuture = _localTransactionExecutor.submit(_completeTransactionRunnable);
            return _transactionOffset;
        }
       
        public void setTransactionDataSizes(long newDataSize, long replacementDataSize, long rollbackDataSize) throws RemoteException {
            _newDataBuffer.setTransactionDataLength(newDataSize);
            _replacementsBuffer.setTransactionDataLength(replacementDataSize);
            _rollbackBuffer.setTransactionDataLength(rollbackDataSize);
        }
       
        @Override
        protected void finalize() throws Throwable
        {
            disposeRemoteContainer();
        }

        public void disposeRemoteContainer() throws IOException {
            _newDataBuffer.close();
            _replacementsBuffer.close();
            _rollbackBuffer.close();
            Future unlockProcess = _localTransactionExecutor.submit(_unlockTransactionRunnable);
            try {
                unlockProcess.get(JodbNetConstants.FILE_TRANSFER_MAX_WAIT, TimeUnit.MILLISECONDS);
            } catch (Exception e) {
                throw new JodbIOException(e);//TODO should be critical error?
            }
            if(JODBConfig.DEBUG){
                Utils.getLogger(getClass().getName()).log(Level.INFO, "Executor shutdown "+_localTransactionExecutor.toString());
            }
            _localTransactionExecutor.shutdownNow();
            UnicastRemoteObject.unexportObject(this, false);
        }

        public void checkTransactionComplete() throws IOException {
            try {
                _transactionFuture.get(JodbNetConstants.DEFAULT_TRANSACTION_LOCK_WAIT_TIMEOUT, TimeUnit.MILLISECONDS);
            } catch (Exception e) {
                throw new JodbIOException(e);
            }
            if(_transactionExecutionError != null){
                throw new JodbIOException(_transactionExecutionError);
            }
        }
       
        private class CompleteTransactionRunnable implements Runnable{

            public void run() {
                try {
                    ensureFileTransferComplete();
                    _ioBase.applyRemoteTransaction(RemoteTransactionContainer.this,_transactionOffset);
                    reloadIndexingRootAgent();//TODO coditional reload (index may not change) for optimization
                } catch (Exception e) {//TODO check Throwable and exit as critical error?
                    _transactionExecutionError = e;
                finally {
                    if(JODBConfig.DEBUG){
                        Utils.getLogger(getClass().getName()).log(Level.INFO, "Lock release "+Thread.currentThread());
                    }
                    _unlockTransactionRunnable.run();
                    _serverSocketAcceptor.removeReciever(_newDataBuffer);
                    _serverSocketAcceptor.removeReciever(_replacementsBuffer);
                    _serverSocketAcceptor.removeReciever(_rollbackBuffer);
                }
            }
           
        }
       
        private class UnlockTransactionRunnable implements Runnable{

            public void run() {
                if(_lock.isWriteLockedByCurrentThread()){
                    _lock.writeLock().unlock();
                }
            }
           
        }
       
        private class LockTransuctionRunnable implements Runnable{
           
            int _transactioLockTimeout=-1;
            boolean _gotLock;
           
            void init(int transactioLockTimeout){
                _transactioLockTimeout = transactioLockTimeout;
                _gotLock = false;
            }
           
            public void run() {
                try {
                    if(JODBConfig.DEBUG){
                        Utils.getLogger(getClass().getName()).log(Level.INFO, "Lock set "+Thread.currentThread());
                    }
                    _gotLock = _lock.writeLock().tryLock(_transactioLockTimeout, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace();//TODO log
                }
            }
        }
       
       
       
    }
   
    private static class FileReceiver implements Runnable  {
        IRandomAccessDataBuffer _file;
        Integer _id;
        long _length=-1;
        long _maxTransferTime;
        ServerSocketAcceptor _container;
        Socket _readSocket;
        Throwable _error;
        boolean _transferComplete;
        boolean _processed;
        Future _transferCompletionSynch;
        Semaphore _transferSubmitSemaphore = new Semaphore(1);
       
       
        public FileReceiver(BUFFER_TYPE bufferType) throws IOException {
            _file = JODBConfig.getRandomAccessBufferFactory().createBuffer("", bufferType, true);
            _id = System.identityHashCode(_file);
            try {
                _transferSubmitSemaphore.acquire();
            } catch (InterruptedException e) {
                throw new JodbIOException(e);
            }
        }

        public Integer getFileId() {
            return _id;
        }
       
        void resetId(){
            _id = _id.intValue();
        }
       
        public void setContainer(ServerSocketAcceptor container) {
            _container = container;
        }
       
        public void setTransactionDataLength(long length) {
            _length = length;
        }
       
        public void close() throws IOException{
            if(_transferSubmitSemaphore.availablePermits() == 0){
                _transferSubmitSemaphore.release();
            }
            _file.close();
            _file.delete();
        }

       
        @Override
        protected void finalize() throws Throwable
        {
            _file.delete();
        }
       
        public void setReadSocket(Socket readSocket) {
            _readSocket = readSocket;
        }
       
        public void run()
        {
            try {
                if(_length == -1){
                    throw new JodbIOException("no client transaction data size available");
                }
                SocketChannel socketChannel = _readSocket.getChannel();
                long transfered = _file.transferFrom(socketChannel, 0, _length);
                if(JODBConfig.DEBUG){
                    Utils.getLogger(getClass().getName()).log(Level.INFO, "Transfered "+ transfered +" to file "+_file);
                }
                /*
                InputStream input = _readSocket.getInputStream();
                byte[] outBuffer = new byte[_readSocket.getReceiveBufferSize()];
                int bytesReceived = 0;
                while ((bytesReceived = input.read(outBuffer)) >= 0) {
                    _file.write(outBuffer, 0, bytesReceived);
                }
                input.close();
                if(_file.length() != _length){
                    throw new JodbIOException("Incorrect transfer size "+_file.length()+"!="+_length);
                }*/
            } catch (Exception e) {
                _error = e;
            }
            _transferComplete = true;
        }
       
        public void submit(ThreadPoolExecutor threadPoolExecutor) {
            _transferCompletionSynch = threadPoolExecutor.submit(this);
            _processed = true;
            _transferSubmitSemaphore.release();
            if(JODBConfig.DEBUG){
                Utils.getLogger(getClass().getName()).log(Level.INFO, "Task submitted "+this);
            }
            //_transferCompletionSynch.get(delay, TimeUnit.MILLISECONDS);
        }
       
        public Future getTransferCompletionSynch(long waitForSynchObject) throws InterruptedException, IOException {
            if(!_transferSubmitSemaphore.tryAcquire(waitForSynchObject, TimeUnit.MILLISECONDS)){
                throw new JodbIOException("Transfer wait timeout");
            }
            _transferSubmitSemaphore.release();
            return _transferCompletionSynch;
        }
    }
   
    private class ServerSocketAcceptor extends Thread{

        Socket _lastAcceptedSocket;
        HashMap<Integer, FileReceiver> _pendingFiles = new HashMap<Integer, FileReceiver>();
        ScheduledThreadPoolExecutor _threadPoolExecutor = new ScheduledThreadPoolExecutor(2);
        boolean _closed = false;
       
        public ServerSocketAcceptor() throws IOException {
            setName("JodbServerSocketAcceptor");
            setDaemon(true);
            startDataServerSocket();
        }

        private ServerSocket _serverSocket;
        private ServerSocketChannel _serverSocketChannel;

        private void startDataServerSocket() throws IOException{
            _serverSocketChannel = SelectorProvider.provider().openServerSocketChannel();
            _serverSocket = _serverSocketChannel.socket();
            _serverSocket.bind(new InetSocketAddress(JodbNetConstants.DEFAULT_DATA_STREAM_PORT));
            //new ServerSocket(JODBConstants.DEFAULT_DATA_STREAM_PORT);
            start();
        }
       
        public void addReciever(FileReceiver fileReceiver){
            synchronized (_pendingFiles) {
                _pendingFiles.put(fileReceiver.getFileId(), fileReceiver);
            }
        }
       
        public void removeReciever(FileReceiver fileReceiver){
            synchronized (_pendingFiles) {
                _pendingFiles.remove(fileReceiver.getFileId());
            }
        }
       
        public void close() throws IOException{
            _closed = true;
            _serverSocket.close();
            _threadPoolExecutor.shutdown();
        }
       
        @Override
        public void run()
        {
            while(true){
                Socket socket;
                try {
                    socket = _serverSocket.accept();
                } catch (IOException e) {
                    if(_closed){
                        break;
                    }
                    Utils.fatalError(e);
                    continue;
                }
                if(_closed){
                    break;
                }
                try {
                    handleConnection(socket);
                } catch (IOException e) {
                    e.printStackTrace();//TODO log
                }
            }
        }
       
        void handleConnection(Socket socket) throws IOException{
            socket.setSoTimeout(JodbNetConstants.FILE_TRANSFER_SOCKET_TIMEOUT);
            DataInputStream is = new DataInputStream(socket.getInputStream());

            int id = new DataInputStream(is).readInt();
            FileReceiver fileReceiver = _pendingFiles.get(id);
            if(fileReceiver == null){
                throw new JodbIOException("File Id is not available "+id);
            }
            fileReceiver.setReadSocket(socket);

            fileReceiver.submit(_threadPoolExecutor);
            removeReciever(fileReceiver);
           
            if(JODBConfig.DEBUG){
                Utils.getLogger(getClass().getName()).log(Level.INFO, "Task finished "+this);
            }
        }       
    }
   
    class DatabaseStatisticsSE  implements IDatabaseStatisticsRemote{
       
        boolean _exported;
        IDatabaseStatistics _databaseStatistics;

        public DatabaseStatisticsSE() throws IOException {
        }
       
        public void setDatabaseStatistics(IDatabaseStatistics databaseStatistics) {
            _databaseStatistics = databaseStatistics;
        }
       
        public long literalSubstFreeSize(int tableIndex) throws IOException {
            return _databaseStatistics.literalSubstFreeSize(tableIndex);
        }

        public long literalSubstMaxSize(int tableIndex) throws IOException {
            return _databaseStatistics.literalSubstMaxSize(tableIndex);
        }

        public int totalDataEntries() throws IOException {
            return _databaseStatistics.totalDataEntries();
        }

        public synchronized boolean isExported() {
            return _exported;
        }
       
        public synchronized void export() throws IOException {
            if(_exported){
                return;
            }
            _exported = true;
            UnicastRemoteObject.exportObject(this, JodbNetConstants.DEFAULT_RMI_PORT);
        }

        public synchronized void unexport() throws IOException {
            if(!_exported){
                return;
            }
            _exported = false;
            UnicastRemoteObject.unexportObject(this, true);
            //System.gc();
        }
       
       
//        @Override
//        protected void finalize() throws Throwable
//        {
//            _logger.log(Level.SEVERE,"finalize- "+this);
//        }
//
//        public void unreferenced() {
//            _logger.log(Level.SEVERE,"unreferenced- "+this);
//        }
    }
   
}
TOP

Related Classes of com.mobixess.jodb.core.JODBServer$RemoteTransactionContainer$UnlockTransactionRunnable

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.