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

org.neo4j.helpers.FutureAdapter Maven / Gradle / Ivy

/*
 * Copyright (c) 2018-2020 "Graph Foundation,"
 * Graph Foundation, Inc. [https://graphfoundation.org]
 *
 * This file is part of ONgDB.
 *
 * ONgDB is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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, see .
 */
/*
 * Copyright (c) 2002-2020 "Neo4j,"
 * Neo4j Sweden AB [http://neo4j.com]
 *
 * This file is part of Neo4j.
 *
 * Neo4j is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program 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, see .
 */
package org.neo4j.helpers;

import java.util.concurrent.Callable;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.function.Supplier;

public abstract class FutureAdapter implements Future
{
    public static final Future VOID = CompletableFuture.completedFuture( null );

    @Override
    public boolean cancel( boolean mayInterruptIfRunning )
    {
        throw new UnsupportedOperationException();
    }

    @Override
    public boolean isCancelled()
    {
        throw new UnsupportedOperationException();
    }

    /**
     * This class will be deleted as part of next major release. Please use {@link CompletableFuture#complete(Object)}
     * instead.
     */
    @Deprecated
    public static class Present extends FutureAdapter
    {
        private final V value;

        public Present( V value )
        {
            this.value = value;
        }

        @Override
        public boolean isDone()
        {
            return true;
        }

        @Override
        public V get()
        {
            return value;
        }
        @Override
        public V get( long timeout, TimeUnit unit )
        {
            return value;
        }
    }

    /**
     * @param  type of values that this {@link Future} have.
     * @param value result value.
     * @return {@link Present} future with already specified result
     *
     * This method will be deleted as part of next major release. Please use {@link CompletableFuture#complete(Object)}
     * instead.
     */
    @Deprecated
    public static  Present present( T value )
    {
        return new Present<>( value );
    }

    public static  Future latchGuardedValue( final Supplier supplier, final CountDownLatch guardedByLatch,
                                                   final String jobDescription )
    {
        return new FutureAdapter()
        {
            @Override
            public boolean isDone()
            {
                return guardedByLatch.getCount() == 0;
            }

            @Override
            public T get() throws InterruptedException
            {
                guardedByLatch.await();
                return supplier.get();
            }

            @Override
            public T get( long timeout, TimeUnit unit ) throws InterruptedException, TimeoutException
            {
                if ( !guardedByLatch.await( timeout, unit ) )
                {
                    throw new TimeoutException( jobDescription + " didn't complete within " +
                            timeout + " " + unit );
                }
                return supplier.get();
            }
        };
    }

    public static Future processFuture( final Process process )
    {
        return new FutureAdapter()
        {
            @Override
            public boolean isDone()
            {
                return tryGetExitValue( process ) != null;
            }

            private Integer tryGetExitValue( final Process process )
            {
                try
                {
                    return process.exitValue();
                }
                catch ( IllegalThreadStateException e )
                {   // Thrown if this process hasn't exited yet.
                    return null;
                }
            }

            @Override
            public Integer get() throws InterruptedException
            {
                return process.waitFor();
            }

            @Override
            public Integer get( long timeout, TimeUnit unit ) throws InterruptedException, TimeoutException
            {
                long end = System.currentTimeMillis() + unit.toMillis( timeout );
                while ( System.currentTimeMillis() < end )
                {
                    Integer result = tryGetExitValue( process );
                    if ( result != null )
                    {
                        return result;
                    }
                    Thread.sleep( 10 );
                }
                throw new TimeoutException( "Process '" + process + "' didn't exit within " + timeout + " " + unit );
            }
        };
    }

    public static  Future future( final Callable task )
    {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        Future future = executor.submit( task );
        executor.shutdown();
        return future;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy