Package com.aelitis.azureus.core.lws

Source Code of com.aelitis.azureus.core.lws.LightWeightSeed

/*
* Created on Jul 16, 2008
* Created by Paul Gardner
*
* Copyright 2008 Vuze, Inc.  All rights reserved.
*
* This program 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; version 2 of the License only.
*
* 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, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
*/


package com.aelitis.azureus.core.lws;

import java.io.File;
import java.net.InetSocketAddress;
import java.net.URL;

import org.gudy.azureus2.core3.disk.DiskManager;
import org.gudy.azureus2.core3.disk.DiskManagerReadRequest;
import org.gudy.azureus2.core3.disk.DiskManagerReadRequestListener;
import org.gudy.azureus2.core3.logging.LogEvent;
import org.gudy.azureus2.core3.logging.LogIDs;
import org.gudy.azureus2.core3.logging.LogRelation;
import org.gudy.azureus2.core3.logging.Logger;
import org.gudy.azureus2.core3.peer.PEPeer;
import org.gudy.azureus2.core3.peer.PEPeerManager;
import org.gudy.azureus2.core3.peer.PEPeerManagerFactory;
import org.gudy.azureus2.core3.peer.PEPeerManagerListener;
import org.gudy.azureus2.core3.peer.PEPiece;
import org.gudy.azureus2.core3.peer.util.PeerUtils;
import org.gudy.azureus2.core3.torrent.TOTorrent;
import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncer;
import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerDataProvider;
import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerException;
import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerFactory;
import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerListener;
import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponse;
import org.gudy.azureus2.core3.tracker.client.TRTrackerAnnouncerResponsePeer;
import org.gudy.azureus2.core3.util.ByteFormatter;
import org.gudy.azureus2.core3.util.HashWrapper;
import org.gudy.azureus2.core3.util.SystemTime;
import org.gudy.azureus2.plugins.torrent.Torrent;
import org.gudy.azureus2.pluginsimpl.local.torrent.TorrentImpl;

import com.aelitis.azureus.core.networkmanager.NetworkConnection;
import com.aelitis.azureus.core.networkmanager.NetworkManager;
import com.aelitis.azureus.core.peermanager.PeerManager;
import com.aelitis.azureus.core.peermanager.PeerManagerRegistration;
import com.aelitis.azureus.core.peermanager.PeerManagerRegistrationAdapter;
import com.aelitis.azureus.core.peermanager.peerdb.PeerItem;



public class
LightWeightSeed
  extends LogRelation
  implements PeerManagerRegistrationAdapter
{
  private static final byte  ACT_NONE          = 0;
  private static final byte  ACT_HAS_PEERS        = 2;
  private static final byte  ACT_HAS_POTENTIAL_PEERS    = 3;
  private static final byte  ACT_INCOMING        = 4;
  private static final byte  ACT_NO_PM          = 5;
  private static final byte  ACT_TIMING_OUT        = 6;
  private static final byte  ACT_TRACKER_ANNOUNCE    = 7;
  private static final byte  ACT_TRACKER_SCRAPE      = 8;
 
  private static final int DEACTIVATION_TIMEOUT          = 5*60*1000;
  private static final int DEACTIVATION_WITH_POTENTIAL_TIMEOUT  = 15*60*1000;

  private LightWeightSeedManager    manager;
  private LightWeightSeedAdapter    adapter;
  private String            name;
  private HashWrapper          hash;
  private URL              announce_url;
  private File            data_location;
 
  private PeerManagerRegistration    peer_manager_registration;

  private PEPeerManager        peer_manager;
  private LWSDiskManager        disk_manager;
  private LWSDownload          pseudo_download;
  private LWSTorrent          torrent_facade;
  private TRTrackerAnnouncer      announcer;
 
  private TOTorrent          actual_torrent;
 
  private boolean    is_running;
  private long    last_activity_time;
  private int      activation_state    = ACT_NONE;
 
  protected
  LightWeightSeed(
    LightWeightSeedManager  _manager,
    String          _name,
    HashWrapper        _hash,
    URL            _announce_url,
    File          _data_location,
    LightWeightSeedAdapter  _adapter )
  {
    manager      = _manager;
    name      = _name;
    hash      = _hash;
    announce_url  = _announce_url;
    data_location  = _data_location;
    adapter      = _adapter;
  }
 
  protected String
  getName()
  {
    return( name + "/" + ByteFormatter.encodeString( hash.getBytes()));
  }
 
  protected Torrent
  getTorrent()
  {
    return( new TorrentImpl( getTOTorrent( false )));
  }
 
  protected TOTorrent
  getTOTorrent(
    boolean    actual )
  {
    if ( actual ){
     
      synchronized( this ){
       
        if ( actual_torrent == null ){
         
          try{
         
            actual_torrent = adapter.getTorrent( hash.getBytes(), announce_url, data_location );
           
          }catch( Throwable e ){
           
            log( "Failed to get torrent", e );
          }
         
          if ( actual_torrent == null ){
           
            throw( new RuntimeException( "Torrent not available" ));
          }
        }
       
        return( actual_torrent );
      }
    }else{
     
      return( torrent_facade );
    }
  }
 
  public HashWrapper
  getHash()
  {
    return( hash );
  }
 
  public URL
  getAnnounceURL()
  {
    return( announce_url );
  }
 
  public File
  getDataLocation()
  {
    return( data_location );
  }
 
  protected long
  getSize()
  {
    return( data_location.length());
  }
 
  public boolean
  isPeerSourceEnabled(
    String    peer_source )
  {
    return( true );
  }
 
  public boolean
  manualRoute(
    NetworkConnection connection )
  {
    return false;
  }
 
  public byte[][]
  getSecrets()
  {
    return( new byte[][]{ hash.getBytes()});
  }
 
  public boolean
  activateRequest(
    InetSocketAddress    remote_address )
  {
    ensureActive( "Incoming[" + remote_address.getAddress().getHostAddress() + "]", ACT_INCOMING );
   
    return( true );
  }
 
  public void
  deactivateRequest(
    InetSocketAddress    remote_address )
  {
   
  }
 
  public String
  getDescription()
  {
    return( "LWS: " + getName());
  }
 
  protected synchronized void
  start()
  {
    log( "Start" );
       
    if ( is_running ){
     
      log( "Start of '" + getString() + "' failed - already running" );

      return;
    }
   
    if ( peer_manager_registration != null ){
     
      log( "Start of '" + getString() + "' failed - router already registered" );

      return;
    }
   
    if ( pseudo_download != null ){
     
      log( "Start of '" + getString() + "' failed - pseudo download already registered" );

      return;
    }
   
    if ( disk_manager != null ){
     
      log( "Start of '" + getString() + "' failed - disk manager already started" );
     
      return;
    }
 
    if ( peer_manager != null ){
     
      log( "Start of '" + getString() + "' failed - peer manager already started" );
     
      return;
    }
   
    try{
      if ( torrent_facade == null ){
       
        torrent_facade = new LWSTorrent( this );
      }
     
      peer_manager_registration = PeerManager.getSingleton().registerLegacyManager( hash, this );
     
      announcer = createAnnouncer();
       
      pseudo_download = new LWSDownload( this, announcer );
       
      manager.addToDHTTracker( pseudo_download );
   
      is_running  = true;

      last_activity_time = SystemTime.getMonotonousTime();
     
    }catch( Throwable e ){
           
      log( "Start of '" + getString() + "' failed", e );
     
    }finally{
     
      if ( is_running ){
                   
        log( "Started " + getString());

      }else{
       
        stop();
      }
    }
  }
 
  protected synchronized void
  stop()
  {
    log( "Stop" );
   
    try{
      if ( disk_manager != null ){
       
        disk_manager.stop( false );
     
        disk_manager  = null;   
      }
     
      if ( peer_manager != null ){
       
        peer_manager.stopAll();
       
        peer_manager = null;
      }

      if ( pseudo_download != null ){
       
        manager.removeFromDHTTracker( pseudo_download );
       
        pseudo_download = null;
      }

      if ( announcer != null ){
       
        announcer.stop( false );
       
        announcer.destroy();
       
        announcer = null;
      }
     
      if ( peer_manager_registration != null ){
       
        peer_manager_registration.unregister();
       
        peer_manager_registration  = null;
      }
           
    }finally{
     
      is_running   = false;
     
      activation_state   = ACT_NONE;
     
      log( "Stopped " + getString());
    }
  }
 
  protected synchronized void
  activate(
    String    reason_str,
    byte    activation_reason )
  {
    log( "Activate: " + activation_reason + "/" + reason_str );
   
    if ( activation_state != ACT_NONE ){
     
      return;
    }
   
    try{     
      disk_manager = new LWSDiskManager( this, data_location );
     
      disk_manager.start();
     
      if ( disk_manager.getState() != DiskManager.READY ){
                 
        log( "Start of '" + getString() + "' failed, disk manager failed = " + disk_manager.getErrorMessage());
       
      }else{
       
        peer_manager =
          PEPeerManagerFactory.create(
                announcer.getPeerId(),
                new LWSPeerManagerAdapter(
                    this,
                    peer_manager_registration ),
                disk_manager );
 
        peer_manager.addListener(
          new PEPeerManagerListener()
          {
            public void
            peerAdded(
              final PEPeerManager   manager,
              final PEPeer       peer )
            {
              last_activity_time = SystemTime.getMonotonousTime();
            }
             

            public void
            peerRemoved(
              PEPeerManager   manager,
              PEPeer       peer )
            {
              last_activity_time = SystemTime.getMonotonousTime();
            }
           
            public void
            peerDiscovered(
              PEPeerManager manager,
              PeerItem peer,
              PEPeer finder)
            {
            }
             
            public void
            pieceAdded(
              PEPeerManager   manager,
              PEPiece     peice,
              PEPeer       for_peer )
            {
            }
             
            public void
            pieceRemoved(
              PEPeerManager   manager,
              PEPiece     peice )
            {
            }

            public void
            peerSentBadData(
              PEPeerManager   manager,
              PEPeer       peer,
              int       pieceNumber)
            {             
            }
            public void
            destroyed()
            {
            }
          });
       
        peer_manager.start();
     
        announcer.update( true );
                     
        activation_state  = activation_reason;
       
        last_activity_time = SystemTime.getMonotonousTime();
      }
     
    }catch( Throwable e ){
           
      log( "Activation of '" + getString() + "' failed", e );
     
    }finally{
     
      if ( activation_state != ACT_NONE ){
         

      }else{
       
        deactivate();
      }
    }
  }
 
  protected synchronized void
  deactivate()
  {
    log( "Deactivate" );

    try{
      if ( disk_manager != null ){
       
        disk_manager.stop( false );
     
        disk_manager  = null;   
      }
     
      if ( peer_manager != null ){
       
        peer_manager.stopAll();
       
        peer_manager = null;
      }
    }finally{
     
      activation_state = ACT_NONE;
    }
  }
 
  protected synchronized TRTrackerAnnouncer
  createAnnouncer()   
    throws TRTrackerAnnouncerException
  {
   
      // use a facade here to delay loading the actual torrent until the
      // download is activated
 
    TRTrackerAnnouncer result = TRTrackerAnnouncerFactory.create( torrent_facade, true );
   
    result.addListener(
        new TRTrackerAnnouncerListener()
        {
          public void
          receivedTrackerResponse(
            TRTrackerAnnouncerResponse  response )
          {
            TRTrackerAnnouncerResponsePeer[] peers = response.getPeers();
           
              // tracker shouldn't return seeds to seeds to we can assume
              // that if peers returned this means we have someone to talk to
         
            if ( peers != null && peers.length > 0 ){
           
              ensureActive( "Tracker[" + peers[0].getAddress()+ "]", ACT_TRACKER_ANNOUNCE );
             
            }else if ( response.getScrapeIncompleteCount() > 0 ){
             
              ensureActive( "Tracker[scrape]", ACT_TRACKER_SCRAPE );
            }
           
            PEPeerManager  pm = peer_manager;
           
            if ( pm != null ){
                             
              pm.processTrackerResponse( response );
            }
          }
 
          public void
          urlChanged(
            TRTrackerAnnouncer  announcer,
            URL          old_url,
            URL          new_url,
            boolean        explicit )
          {
          }
           
          public void
          urlRefresh()
          { 
          }
        });
     
    result.setAnnounceDataProvider(
        new TRTrackerAnnouncerDataProvider()
        {
          public String
          getName()
          {
            return( LightWeightSeed.this.getName());
          }
         
          public long
          getTotalSent()
          {
            return( 0 );
          }
         
          public long
          getTotalReceived()
          {
            return( 0 );
          }
         
            public long
            getFailedHashCheck()
            {
              return( 0 );
            }
           
          public long
          getRemaining()
          {
            return( 0 );
          }
         
          public String
          getExtensions()
          {
            return( null );
          }
         
          public int
          getMaxNewConnectionsAllowed()
          {
            PEPeerManager  pm = peer_manager;

            if ( pm == null ){
             
                // got to ask for at least one to trigger activation!
             
              return( 8 );
            }
           
            return( PeerUtils.numNewConnectionsAllowed( pm.getPeerIdentityDataID(),0));
          }
         
          public int
          getPendingConnectionCount()
          {
            PEPeerManager  pm = peer_manager;

            if ( pm == null ){
             
              return( 0 );
            }
           
            return( pm.getPendingPeerCount());
          }
         
          public int
          getConnectedConnectionCount()
          {
            PEPeerManager  pm = peer_manager;

            if ( pm == null ){
             
              return( 0 );
            }
           
            return( pm.getNbPeers() + pm.getNbSeeds());
          }
         
          public int
          getUploadSpeedKBSec(
            boolean estimate)
          {
            return 0;
          }
         
          public int
          getCryptoLevel()
          {
            return( NetworkManager.CRYPTO_OVERRIDE_NONE );
          }
         
          public boolean
          isPeerSourceEnabled(
            String    peer_source )
          {
            return( true );
          }
         
          public void
          setPeerSources(
            String[]  sources )
          {
          }
        });
   
    return( result );
  }
 
  protected synchronized void
  ensureActive(
    String  reason,
    byte  a_reason )
  {
    if ( is_running && activation_state == ACT_NONE ){
     
      activate( reason, a_reason );
    }
  }
 
  protected synchronized void
  checkDeactivation()
  {
    if ( activation_state == ACT_NONE ){
     
      return;
    }
   
    if ( peer_manager == null ){
     
      activation_state  = ACT_NO_PM;
     
      return;
    }

   
    if ( peer_manager.getNbPeers() > 0 ){
     
      activation_state  = ACT_HAS_PEERS;

      return;
    }
   
    long  now = SystemTime.getMonotonousTime();
       
    long  millis_since_last_act = now - last_activity_time;
   
    if ( peer_manager.hasPotentialConnections()){
     
      if ( millis_since_last_act < DEACTIVATION_WITH_POTENTIAL_TIMEOUT ){
       
        activation_state  = ACT_HAS_POTENTIAL_PEERS;

        return;
      }
    }
   
    if ( millis_since_last_act >= DEACTIVATION_TIMEOUT ){
     
      deactivate();
     
    }else{
     
      activation_state  = ACT_TIMING_OUT;
    }
  }
 
  public void
  enqueueReadRequest(
    PEPeer              peer,
    DiskManagerReadRequest       request,
    DiskManagerReadRequestListener   listener )
  {
    LWSDiskManager  dm = disk_manager;
   
    if ( dm == null ){
     
      listener.readFailed( request, new Throwable( "download is stopped" ));
     
    }else{
   
      dm.enqueueReadRequest( request, listener );
    }
  }
 
  public void
  remove()
  {
    manager.remove( this );
  }
 
  public String
  getRelationText()
  {
    return "LWS: '" + getName() + "'";
  }

  public Object[]
  getQueryableInterfaces()
  {
    return new Object[]{};
  }
 
  public LogRelation
  getRelation()
  {
    return( this );
  }
 
  protected String
  getString()
  {
    return( getName());
  }
 
  protected void
  log(
    String    str )
  {
    Logger.log(new LogEvent(this, LogIDs.CORE, str ));
  }
 
  protected void
  log(
    String    str,
    Throwable  e )
  {
    Logger.log(new LogEvent(this, LogIDs.CORE, str, e ));
  }
}
TOP

Related Classes of com.aelitis.azureus.core.lws.LightWeightSeed

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.