Package org.hive2hive.core.network.data.download

Source Code of org.hive2hive.core.network.data.download.DownloadManager$DownloadListener

package org.hive2hive.core.network.data.download;

import java.io.File;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.hive2hive.core.H2HConstants;
import org.hive2hive.core.api.interfaces.IFileConfiguration;
import org.hive2hive.core.model.MetaChunk;
import org.hive2hive.core.network.data.IDataManager;
import org.hive2hive.core.network.data.PublicKeyManager;
import org.hive2hive.core.network.messages.IMessageManager;
import org.hive2hive.core.processes.implementations.files.download.dht.DownloadChunkRunnableDHT;
import org.hive2hive.core.processes.implementations.files.download.dht.DownloadTaskDHT;
import org.hive2hive.core.processes.implementations.files.download.direct.DownloadChunkRunnableDirect;
import org.hive2hive.core.processes.implementations.files.download.direct.DownloadTaskDirect;
import org.hive2hive.core.processes.implementations.files.download.direct.GetLocationsList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* A download manager handling downloads. Downloading chunks happens concurrently. It is possible to download
* multiple files at a time. The number of concurrent downloads is configurable over the
* {@link H2HConstants#CONCURRENT_DOWNLOADS} field. <br>
* Downloaded chunks are stored in a temporary folder and assembled when all chunks are downloaded.
*
* @author Nico
*
*/
public class DownloadManager {

  private final static Logger logger = LoggerFactory.getLogger(DownloadManager.class);

  private final IDataManager dataManager;
  private final IMessageManager messageManager;
  private final PublicKeyManager keyManager;
  private final IFileConfiguration fileConfig;
  private final Set<BaseDownloadTask> openTasks;

  private ExecutorService executor;

  public DownloadManager(IDataManager dataManager, IMessageManager messageManager, PublicKeyManager keyManager,
      IFileConfiguration fileConfig) {
    this.dataManager = dataManager;
    this.messageManager = messageManager;
    this.keyManager = keyManager;
    this.fileConfig = fileConfig;
    this.executor = Executors.newFixedThreadPool(H2HConstants.CONCURRENT_DOWNLOADS);
    this.openTasks = Collections.newSetFromMap(new ConcurrentHashMap<BaseDownloadTask, Boolean>());
  }

  /**
   * Add a new task to download a file. The download is automatically started in the background
   */
  public void submit(BaseDownloadTask task) {
    logger.debug("Submitted to download {}", task.getDestinationName());

    // store the task for possible later recovery
    openTasks.add(task);

    // add a listener
    task.addListener(new DownloadListener());

    // start the execution
    schedule(task);
  }

  private void schedule(BaseDownloadTask task) {
    if (task.isDirectDownload()) {
      // first get the locations of all users having access to this file
      DownloadTaskDirect directTask = (DownloadTaskDirect) task;
      // Hint: Run it in a separate thread (not in the thread pool) because the executor does not
      // guarantee the in-order processing.
      new Thread(new GetLocationsList(directTask, dataManager)).start();

      // then download all chunks in separate threads
      for (MetaChunk chunk : task.getOpenChunks()) {
        DownloadChunkRunnableDirect runnable = new DownloadChunkRunnableDirect(directTask, chunk, messageManager,
            keyManager, fileConfig);
        executor.submit(runnable);
      }
    } else {
      // submit each chunk as a separate thread
      for (MetaChunk chunk : task.getOpenChunks()) {
        DownloadChunkRunnableDHT runnable = new DownloadChunkRunnableDHT((DownloadTaskDHT) task, chunk, dataManager);
        executor.submit(runnable);
      }
    }
  }

  /**
   * Stop the downloads
   */
  public void stopBackgroundProcesses() {
    executor.shutdownNow();
    while (!executor.isTerminated()) {
      logger.debug("Waiting for executor to shutdown...");
    }
  }

  /**
   * Continue with the downloads
   */
  public void continueBackgroundProcess() {
    executor = Executors.newFixedThreadPool(H2HConstants.CONCURRENT_DOWNLOADS);
    for (BaseDownloadTask task : openTasks) {
      schedule(task);
    }
  }

  /**
   * Return the task which are currently downloading or waiting for a download slot
   */
  public Set<BaseDownloadTask> getOpenTasks() {
    return openTasks;
  }

  /**
   * Indicates whether the download manager has already a task to download the given file
   */
  public boolean isDownloading(File file) {
    for (BaseDownloadTask openTask : openTasks) {
      if (openTask.getDestination().equals(file))
        return true;
    }

    return false;
  }

  /**
   * Listens for a download to finish and removes it from the open list
   */
  private class DownloadListener implements IDownloadListener {

    @Override
    public void downloadFinished(BaseDownloadTask task) {
      // remove it from the task list
      openTasks.remove(task);
      logger.debug("Task for downloading {} finished", task.getDestinationName());
    }

    @Override
    public void downloadFailed(BaseDownloadTask task, String reason) {
      // remove it from the task anyway
      openTasks.remove(task);
      logger.debug("Task for downloading {} failed", task.getDestinationName());
    }

  }
}
TOP

Related Classes of org.hive2hive.core.network.data.download.DownloadManager$DownloadListener

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.