use of com.biglybt.core.peer.PEPeerManager in project BiglyBT by BiglySoftware.
the class DownloadManagerImpl method getNATStatus.
@Override
public Object[] getNATStatus() {
int state = getState();
PEPeerManager peerManager = controller.getPeerManager();
TRTrackerAnnouncer tc = getTrackerClient();
final int nat_status;
final String nat_info;
if (tc != null && peerManager != null && (state == STATE_DOWNLOADING || state == STATE_SEEDING)) {
int rem_tcp = peerManager.getNbRemoteTCPConnections();
int rem_utp = peerManager.getNbRemoteUTPConnections();
if (rem_tcp > 0 || rem_utp > 0) {
nat_status = ConnectionManager.NAT_OK;
nat_info = "Has remote " + (rem_tcp > 0 ? "TCP" : "uTP") + " connections";
} else {
long last_good_time = peerManager.getLastRemoteConnectionTime();
if (last_good_time > 0) {
if (SystemTime.getCurrentTime() - last_good_time < 30 * 60 * 1000) {
nat_status = ConnectionManager.NAT_OK;
nat_info = "Had a recent remote connection";
} else {
nat_status = ConnectionManager.NAT_PROBABLY_OK;
nat_info = "Had a remote connection at some point";
}
} else {
TRTrackerAnnouncerResponse announce_response = tc.getLastResponse();
int trackerStatus = announce_response.getStatus();
if (trackerStatus == TRTrackerAnnouncerResponse.ST_OFFLINE || trackerStatus == TRTrackerAnnouncerResponse.ST_REPORTED_ERROR) {
nat_status = ConnectionManager.NAT_UNKNOWN;
nat_info = "Tracker offline";
} else if (SystemTime.getCurrentTime() - peerManager.getTimeStarted(false) < 3 * 60 * 1000) {
// tracker's ok but no remotes - give it some time
nat_status = ConnectionManager.NAT_UNKNOWN;
nat_info = "Tracker OK but not remote connections yet";
} else {
TRTrackerScraperResponse scrape_response = getTrackerScrapeResponse();
if (scrape_response != null && scrape_response.isValid()) {
if (peerManager.getNbSeeds() == scrape_response.getSeeds() && peerManager.getNbPeers() == scrape_response.getPeers()) {
nat_status = ConnectionManager.NAT_UNKNOWN;
nat_info = "Connected to all known peers, hard to tell";
} else if (state == STATE_SEEDING && scrape_response.getPeers() == 0) {
// can't expect incoming if we're seeding and there are no peers
nat_status = ConnectionManager.NAT_UNKNOWN;
nat_info = "Seeding and no peers, status can't be determined";
} else {
nat_status = ConnectionManager.NAT_BAD;
nat_info = "There are peers, we should get some remote connections";
}
} else {
if (state == STATE_SEEDING) {
nat_status = ConnectionManager.NAT_UNKNOWN;
nat_info = "Tracker info unavailable and we're seeding, hard to tell";
} else {
nat_status = ConnectionManager.NAT_BAD;
nat_info = "Tracker info unavailable, assuming bad";
}
}
}
}
}
} else {
nat_status = ConnectionManager.NAT_UNKNOWN;
nat_info = "Download not running, can't determine status";
}
return (new Object[] { nat_status, nat_info });
}
use of com.biglybt.core.peer.PEPeerManager in project BiglyBT by BiglySoftware.
the class DownloadManagerRateController method update.
static void update() {
tick_count++;
if ((!enable_limit_handling) || pm_map.size() == 0 || NetworkManager.isSeedingOnlyUploadRate() || NetworkManager.getMaxUploadRateBPSNormal() != 0 || core == null || speed_manager == null || speed_manager.getSpeedTester() == null) {
rate_limit = 0;
return;
}
int num_complete = 0;
int num_incomplete = 0;
int num_interesting = 0;
int i_up_total = 0;
int c_up_total = 0;
long mono_now = SystemTime.getMonotonousTime();
for (Map.Entry<PEPeerManager, PMState> entry : pm_map.entrySet()) {
PEPeerManager pm = entry.getKey();
PMState state = entry.getValue();
boolean is_complete = !pm.hasDownloadablePiece();
PEPeerManagerStats pm_stats = pm.getStats();
long up_bytes = pm_stats.getTotalDataBytesSentNoLan() + pm_stats.getTotalProtocolBytesSentNoLan();
long diff = state.setBytesUp(up_bytes);
if (is_complete) {
num_complete++;
c_up_total += diff;
} else {
num_incomplete++;
i_up_total += diff;
if (state.isInteresting(mono_now)) {
num_interesting++;
}
}
if (state.isComplete() != is_complete) {
if (is_complete) {
pm.addRateLimiter(limiter, true);
} else {
pm.removeRateLimiter(limiter, true);
}
state.setComplete(is_complete);
}
}
if (num_incomplete == 0 || num_complete == 0 || num_interesting == 0) {
rate_limit = 0;
return;
}
boolean skipped_tick = false;
if (last_tick_processed != tick_count - 1) {
pm_last_bad_limit = 0;
latest_choke = 0;
wait_until_tick = 0;
ticks_to_sample_start = 0;
sample_num = 0;
incomplete_samples = 0;
complete_samples = 0;
skipped_tick = true;
}
last_tick_processed = tick_count;
if (skipped_tick || tick_count < wait_until_tick) {
return;
}
try {
long real_now = SystemTime.getCurrentTime();
SpeedManagerPingMapper mapper = speed_manager.getActiveMapper();
if (rate_limit == 0) {
rate_limit = speed_manager.getEstimatedUploadCapacityBytesPerSec().getBytesPerSec();
if (rate_limit == 0) {
rate_limit = DEFAULT_UP_LIMIT;
}
}
SpeedManagerLimitEstimate last_bad = mapper.getLastBadUploadLimit();
if (last_bad != null) {
int last_bad_limit = last_bad.getBytesPerSec();
if (last_bad_limit != pm_last_bad_limit) {
pm_last_bad_limit = last_bad_limit;
SpeedManagerLimitEstimate[] bad_ups = mapper.getBadUploadHistory();
int total = last_bad.getBytesPerSec();
int count = 1;
for (SpeedManagerLimitEstimate bad : bad_ups) {
long t = bad.getWhen();
if (real_now - t <= 30 * 1000 && bad.getBytesPerSec() != last_bad_limit) {
total += bad.getBytesPerSec();
count++;
}
}
latest_choke = total / count;
int new_rate_limit;
if (rate_limit == 0) {
new_rate_limit = latest_choke / 2;
} else {
new_rate_limit = rate_limit / 2;
}
if (new_rate_limit < slack_bytes_per_sec) {
new_rate_limit = slack_bytes_per_sec;
}
rate_limit = new_rate_limit;
wait_until_tick = tick_count + WAIT_AFTER_CHOKE_TICKS;
ticks_to_sample_start = 0;
sample_num = 0;
complete_samples = 0;
incomplete_samples = 0;
last_rate_limit = 0;
return;
}
}
if (ticks_to_sample_start > 0) {
ticks_to_sample_start--;
} else if (sample_num < SAMPLE_COUNT) {
complete_samples += c_up_total;
incomplete_samples += i_up_total;
sample_num++;
} else {
double incomplete_average = incomplete_samples / SAMPLE_COUNT;
double complete_average = complete_samples / SAMPLE_COUNT;
double overall_average = (complete_samples + incomplete_samples) / SAMPLE_COUNT;
int action = -1;
try {
if (last_rate_limit == 0) {
action = 1;
} else {
double overall_change = overall_average - last_overall_average;
if (overall_change < 0) {
if (rate_limit < last_rate_limit) {
// System.out.println( "average decreased" );
action = 1;
} else {
action = 0;
}
} else {
double last_ratio = last_incomplete_average / last_complete_average;
double ratio = incomplete_average / complete_average;
if (rate_limit < last_rate_limit && ratio >= last_ratio) {
action = -1;
} else if (rate_limit > last_rate_limit && ratio <= last_ratio) {
double i_up_change = incomplete_average - last_incomplete_average;
if (i_up_change >= 1024) {
action = -1;
} else {
action = 1;
}
} else {
action = 1;
}
}
}
} finally {
int new_rate_limit;
if (action > 0) {
int ceiling = latest_choke == 0 ? DEFAULT_UP_LIMIT : latest_choke;
int diff = (ceiling - rate_limit) / 4;
if (diff > MAX_UP_DIFF) {
diff = MAX_UP_DIFF;
} else if (diff < MIN_DIFF) {
diff = MIN_DIFF;
}
new_rate_limit = rate_limit + diff;
if (new_rate_limit > 100 * 1024 * 1024) {
new_rate_limit = 100 * 1024 * 1024;
}
} else if (action < 0) {
int diff = rate_limit / 5;
if (diff > MAX_DOWN_DIFF) {
diff = MAX_DOWN_DIFF;
} else if (diff < MIN_DIFF) {
diff = MIN_DIFF;
}
new_rate_limit = rate_limit - diff;
if (new_rate_limit < slack_bytes_per_sec) {
new_rate_limit = slack_bytes_per_sec;
}
} else {
new_rate_limit = rate_limit;
}
last_rate_limit = rate_limit;
last_overall_average = overall_average;
last_complete_average = complete_average;
last_incomplete_average = incomplete_average;
rate_limit = new_rate_limit;
sample_num = 0;
complete_samples = 0;
incomplete_samples = 0;
}
}
} finally {
// System.out.println( "rate=" + DisplayFormatters.formatByteCountToKiBEtcPerSec( rate_limit ) + ", last_choke=" + latest_choke );
}
}
use of com.biglybt.core.peer.PEPeerManager in project BiglyBT by BiglySoftware.
the class CoreImpl method checkCloseActions.
protected void checkCloseActions() {
List<DownloadManager> managers = getGlobalManager().getDownloadManagers();
boolean is_downloading = false;
boolean is_seeding = false;
for (DownloadManager manager : managers) {
if (manager.isPaused()) {
return;
}
if (manager.getDownloadState().getFlag(DownloadManagerState.FLAG_METADATA_DOWNLOAD)) {
return;
}
if (manager.getDownloadState().getFlag(DownloadManagerState.FLAG_LOW_NOISE)) {
// don't count these as interesting as the user isn't directly interested in them
continue;
}
int state = manager.getState();
if (state == DownloadManager.STATE_FINISHING) {
is_downloading = true;
} else {
if (state == DownloadManager.STATE_DOWNLOADING) {
PEPeerManager pm = manager.getPeerManager();
if (pm != null) {
if (pm.hasDownloadablePiece()) {
is_downloading = true;
} else {
// its effectively seeding, change so logic about recheck obeyed below
state = DownloadManager.STATE_SEEDING;
}
}
} else {
if (!manager.isDownloadComplete(false)) {
if (state != DownloadManager.STATE_STOPPED && state != DownloadManager.STATE_ERROR) {
// an incomplete download that is in an active state counts as downloading even
// if it is currently queued/waiting as it is 'on its way' to being in a downloading
// state
is_downloading = true;
}
}
}
if (state == DownloadManager.STATE_SEEDING) {
DiskManager disk_manager = manager.getDiskManager();
if (disk_manager != null && disk_manager.getCompleteRecheckStatus() != -1) {
// wait until recheck is complete before we mark as downloading-complete
is_downloading = true;
} else {
is_seeding = true;
}
}
}
}
long now = SystemTime.getMonotonousTime();
if (is_downloading) {
ca_last_time_downloading = now;
ca_last_time_seeding = -1;
} else if (is_seeding) {
ca_last_time_seeding = now;
}
String dl_act = COConfigurationManager.getStringParameter("On Downloading Complete Do");
if (!dl_act.equals("Nothing")) {
if (ca_last_time_downloading >= 0 && !is_downloading && now - ca_last_time_downloading >= 30 * 1000) {
executeInternalCloseAction(true, true, dl_act, null);
}
}
String se_act = COConfigurationManager.getStringParameter("On Seeding Complete Do");
if (!se_act.equals("Nothing")) {
if (ca_last_time_seeding >= 0 && !is_seeding && now - ca_last_time_seeding >= 30 * 1000) {
executeInternalCloseAction(true, false, se_act, null);
}
}
}
use of com.biglybt.core.peer.PEPeerManager in project BiglyBT by BiglySoftware.
the class CoreImpl method checkSleepActions.
protected void checkSleepActions() {
boolean ps_downloading = COConfigurationManager.getBooleanParameter("Prevent Sleep Downloading");
boolean ps_fp_seed = COConfigurationManager.getBooleanParameter("Prevent Sleep FP Seeding");
String tag_name = COConfigurationManager.getStringParameter("Prevent Sleep Tag");
Tag ps_tag = null;
tag_name = tag_name.trim();
if (!tag_name.isEmpty()) {
ps_tag = TagManagerFactory.getTagManager().getTagType(TagType.TT_DOWNLOAD_MANUAL).getTag(tag_name, true);
}
String declining_subsystems = "";
for (PowerManagementListener l : power_listeners) {
try {
if (!l.requestPowerStateChange(PowerManagementListener.ST_SLEEP, null)) {
declining_subsystems += (declining_subsystems.length() == 0 ? "" : ",") + l.getPowerName();
}
} catch (Throwable e) {
Debug.out(e);
}
}
PlatformManager platform = PlatformManagerFactory.getPlatformManager();
if (declining_subsystems.length() == 0 && !(ps_downloading || ps_fp_seed || ps_tag != null)) {
if (platform.getPreventComputerSleep()) {
setPreventComputerSleep(platform, false, "configuration change");
}
return;
}
boolean prevent_sleep = false;
String prevent_reason = null;
if (declining_subsystems.length() > 0) {
prevent_sleep = true;
prevent_reason = "subsystems declined sleep: " + declining_subsystems;
} else if (ps_tag != null && ps_tag.getTaggedCount() > 0) {
prevent_sleep = true;
prevent_reason = "tag '" + tag_name + "' has entries";
} else {
List<DownloadManager> managers = getGlobalManager().getDownloadManagers();
for (DownloadManager manager : managers) {
int state = manager.getState();
if (state == DownloadManager.STATE_FINISHING || manager.getDownloadState().getFlag(DownloadManagerState.FLAG_METADATA_DOWNLOAD)) {
if (ps_downloading) {
prevent_sleep = true;
prevent_reason = "active downloads";
break;
}
} else {
if (state == DownloadManager.STATE_DOWNLOADING) {
PEPeerManager pm = manager.getPeerManager();
if (pm != null) {
if (pm.hasDownloadablePiece()) {
if (ps_downloading) {
prevent_sleep = true;
prevent_reason = "active downloads";
break;
}
} else {
// its effectively seeding, change so logic about recheck obeyed below
state = DownloadManager.STATE_SEEDING;
}
}
}
if (state == DownloadManager.STATE_SEEDING && ps_fp_seed) {
DiskManager disk_manager = manager.getDiskManager();
if (disk_manager != null && disk_manager.getCompleteRecheckStatus() != -1) {
if (ps_downloading) {
prevent_sleep = true;
prevent_reason = "active downloads";
break;
}
} else {
try {
DefaultRankCalculator calc = StartStopRulesDefaultPlugin.getRankCalculator(PluginCoreUtils.wrap(manager));
if (calc.getCachedIsFP()) {
prevent_sleep = true;
prevent_reason = "first-priority seeding";
break;
}
} catch (Throwable e) {
}
}
}
}
}
}
if (prevent_sleep != platform.getPreventComputerSleep()) {
if (prevent_sleep) {
prevent_sleep_remove_trigger = false;
} else {
if (!prevent_sleep_remove_trigger) {
prevent_sleep_remove_trigger = true;
return;
}
}
if (prevent_reason == null) {
if (ps_downloading && ps_fp_seed) {
prevent_reason = "no active downloads or first-priority seeding";
} else if (ps_downloading) {
prevent_reason = "no active downloads";
} else {
prevent_reason = "no active first-priority seeding";
}
}
setPreventComputerSleep(platform, prevent_sleep, prevent_reason);
}
}
use of com.biglybt.core.peer.PEPeerManager in project BiglyBT by BiglySoftware.
the class GlobalManagerImpl method checkSeedingOnlyStateSupport.
protected void checkSeedingOnlyStateSupport() {
boolean seeding = false;
boolean seeding_set = false;
boolean potentially_seeding = false;
List managers = managers_cow;
for (int i = 0; i < managers.size(); i++) {
DownloadManager dm = (DownloadManager) managers.get(i);
PEPeerManager pm = dm.getPeerManager();
int state = dm.getState();
if (dm.getDiskManager() == null || pm == null) {
if (state == DownloadManager.STATE_QUEUED) {
if (dm.isDownloadComplete(false)) {
potentially_seeding = true;
} else {
// Queued and Incomplete means we aren't "only seeding". This
// download WILL start, it just hasn't yet for various reasons
// (1st Priority, etc)
seeding = false;
// can't break out, because we still need to calculate
// potentially_seeding. Set a flag so we don't set "seeding"
// back to true
seeding_set = true;
}
}
continue;
}
if (state == DownloadManager.STATE_DOWNLOADING) {
if (!pm.hasDownloadablePiece()) {
if (!seeding_set) {
seeding = true;
}
} else {
seeding = false;
potentially_seeding = false;
break;
}
} else if (state == DownloadManager.STATE_SEEDING) {
if (!seeding_set) {
seeding = true;
}
}
}
if (seeding) {
potentially_seeding = true;
}
setSeedingOnlyState(seeding, potentially_seeding);
}
Aggregations