/*
 * [RollYourOwnTimeout.java]
 *
 * Summary: How to roll your own timeouts.
 *
 * Copyright: (c) 2016-2017 Roedy Green, Canadian Mind Products, http://mindprod.com
 *
 * Licence: This software may be copied and used freely for any purpose but military.
 *          http://mindprod.com/contact/nonmil.html
 *
 * Requires: JDK 1.8+
 *
 * Created with: JetBrains IntelliJ IDEA IDE http://www.jetbrains.com/idea/
 *
 * Version History:
 *  1.0 2016-06-28 initial version
 */
package com.mindprod.example;

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 static java.lang.System.*;

/**
 * How to roll your own timeouts.
 * <p/>
 * Based on code at http://stackoverflow.com/questions/19456313/simple-timeout-in-java
 *
 * @author Roedy Green, Canadian Mind Products
 * @version 1.0 2016-06-28 initial version
 * @since 2016-06-28
 */
public class RollYourOwnTimeout
    {
    private static final long MILLIS_TO_WAIT = 10 * 1000L;

    /**
     * dummy method to read some data from a website
     */
    private static String requestDataFromWebsite()
        {
        try
            {
            // force timeout to expire
            Thread.sleep( 14_00014_000L );
            }
        catch ( InterruptedException e )
            {
            }
        return "dummy";
        }

    public static void main( final String[] args )
        {
        final ExecutorService executor = Executors.newSingleThreadExecutor();
        // schedule the work
        final Future<String> future = executor.submit( RollYourOwnTimeout::requestDataFromWebsite );
        try
            {
            // where we wait for task to complete
            final String result = future.get( MILLIS_TO_WAIT, TimeUnit.MILLISECONDS );
            out.println( "result: " + result );
            }
        catch ( TimeoutException e )
            {
            err.println( "task timed out" );
            future.cancel( true /* mayInterruptIfRunning */ );
            }
        catch ( InterruptedException e )
            {
            err.println( "task interrupted" );
            }
        catch ( ExecutionException e )
            {
            err.println( "task aborted" );
            }
        executor.shutdownNow();
        }
    }