Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed Reporting Fixes #13263

Closed
wants to merge 2 commits into from
Closed

Conversation

jagannatharjun
Copy link
Member

@jagannatharjun jagannatharjun commented Aug 17, 2020

Basically aims to fix two bugs:

  1. Total Upload speed in bottom bar do not fit with sum of partial Upload speeds #12459
  2. speedplotview assumes speed is updated per second but the default value is 1500ms this causes lots of duplicate data in the calculation for the graph.

m_refreshEnqueued = false;
else
enqueueRefresh();
QTimer::singleShot(1000, this, [this]()
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to make refresh intervals for session stats 2s and remove 1-minute graph.

@Chocobo1 @glassez ?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jagannatharjun Why not make the session stats interval configurable, or perhaps tied to the transfer list refresh interval?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not make the session stats interval configurable,

that will require a lot of work and is not worth it.

perhaps tied to the transfer list refresh interval?

it's already tied in current master and this PR basically untie it

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should provide this statistics in realtime, so I don't mind increasing this interval.
Is it used somewhere other than graphs, where it might be sensitive to such a change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's used in 2 more places, for mainwidow's tooltip and title text, and session statistics window, increasing interval should not be an issue I guess, but our speed plotting mechanism actually assumes a 1-second refresh interval so that requires some work which I already have a patch for. also Deluge also uses 2s interval for stats update

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here's a question out of ignorance; is there anything preventing the Session object from being destructed while this timer is active? resulting in the callback being called and m_nativeSession being a dangling pointer.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

here's a question out of ignorance; is there anything preventing the Session object from being destructed while this timer is active? resulting in the callback being called and m_nativeSession being a dangling pointer.

the function is called in the main loop, so afaik this won't be called after the Session object is destructed (the timer is tied to the lifetime of session object) or while it's being destructed since only one function can execute at a time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to make refresh intervals for session stats 2s and remove 1-minute graph.

I've been using this PR in my main setup for more than 2 months now and felt that 1-minute graph is actually useful plus graphs with 2s update intervals don't look good so in the latest revision, I changed the update interval back to 1s.

@FranciscoPombal
Copy link
Member

@jagannatharjun

speedplotview assumes speed is updated per second but the default value is 1500ms this causes lots of duplicate data in the calculation for the graph.

Any metrics/benchmarks you can provide (e.g. before/after memory usage comparison or something)? How much is this "lots" we're talking about here?

@jagannatharjun
Copy link
Member Author

jagannatharjun commented Aug 30, 2020

Speed plot view uses a fixed-size cyclic buffer, so it can't be the culprit for high memory usage at least. This pr actually tries to fix step like graph plotting, you can try it yourself, change transfer list refresh interval to 1000 you will see much natural graphs

synced-speed

#13263 (comment) this may be helpful for performance.

@@ -2417,6 +2422,16 @@ void Session::configureListeningInterface()
configureDeferred();
}

int Session::globalDownloadRate() const
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we overuse "global" in Session member names? Are there other download/upload rates so we can't just use downloadRate/uploadRate?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one could even argue that these aren't global. they are the session transfer rates. Presumably, if you'd have two Session objects, they could return different values here

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these names were based on other Session members globalUploadSpeedLimit and globalDownloadSpeedLimit, do I still need to change these names (globalDownloadRate -> downloadRate and globalUploadRate -> uploadRate)?

also this comment #13263 (comment)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a stake-holder/approver in this repo, I'm just commenting.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMO, all per-session indicators should have no "global" prefixes (e.g. Session::uploadRate() clearly shows that it's upload rate of all session torrents).

m_refreshEnqueued = false;
else
enqueueRefresh();
QTimer::singleShot(1000, this, [this]()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should provide this statistics in realtime, so I don't mind increasing this interval.
Is it used somewhere other than graphs, where it might be sensitive to such a change?

@@ -4662,15 +4667,19 @@ void Session::handleStateUpdateAlert(const lt::state_update_alert *p)

torrent->handleStateUpdate(status);
updatedTorrents.push_back(torrent);

m_globalDownloadRate += torrent->downloadPayloadRate();
m_globalUploadRate += torrent->uploadPayloadRate();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure you can take into account updated torrents only? Is it impossible that some other torrents have non zero rates?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know maybe @arvidn can help here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in principle I believe it's possible for a torrent to have a non-zero transfer rate that doesn't change, and not be included in an update. It's extremely unlikely to happen though, since transfer rates are specified in bytes per second

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

btw, do we understand where the discrepancy is between the session transfer rates and the sum of the torrent rates? does the session not have a counter for payload-only transfers?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

or is it just the update intervals being different?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we understand where the discrepancy is between the session transfer rates and the sum of the torrent rates?

I think the problem is that the session stats update and torrent update can't be taken at the same "time point" causing discrepancy like these #12459 #8738 (the tab bottom speed is from post_session_stats while torrent speed are updated from post_torrent_updates)

is it just the update intervals being different

we try to always call post_torrent_updates and post_session_updates together but the problem (#12459 #8738) still persists.

@xavier2k6
Copy link
Member

@jagannatharjun would this close #8738 too?

@@ -729,11 +731,12 @@ namespace BitTorrent

int m_numResumeData = 0;
int m_extraLimit = 0;
int m_globalDownloadRate = 0;
int m_globalUploadRate = 0;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not an authority on this code base, but it seems like the global prefix is misleading here. Are there other transfer rates stored in the session? If anything, I would call these payloadDownloadRate and payloadUploadRate, since these counters only count the payload, not protocol overhead.

update SpeedPlotView on session stats update
Libtorrent stats and torrent updates can't be taken at same time, this causes out of sync speed reporting in different parts of GUI like in status bar, this commits adds two new fields in Session class i.e downloadRate and uploadRate which are calculated from torrent updates, they can be used to show global rates in GUI

Use Session::uploadRate and Session::downloadRate in StatusBar and Main Window for reporting global rates
@jagannatharjun
Copy link
Member Author

@glassez @Chocobo1 ping.

m_refreshEnqueued = false;
else
enqueueRefresh();
QTimer::singleShot(STATS_UPDATE_INTERVAL, this, [this]()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use refreshInterval() for it too?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refreshInterval can be changed by the user and its default value is 1500ms. Speedplotview assumes speed is updated per second but actually before this PR, stats are updated on refreshInterval this caused lots of duplicate data in the calculation for the graph depending on the value of refreshInterval. So by updating stats per second, independent of refreshInterval I aims to solve this problem.

Previously session stats are also used to display global rates, but because of limitation in libtorrent they were not in-sync with the aggregate values of torrent speeds from transfer list (#12459) so with second commit we now calculate global download and upload rates by manually totalling individual torrent speed values.

With this session stats are now only used in graphs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refreshInterval can be changed by the user and its default value is 1500ms. Speedplotview assumes speed is updated per second

So you don't think it makes sense to make Speedplotview dependent on the actual refresh interval (instead of some hardcoded value) to have it configurable?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you don't think it makes sense to make Speedplotview dependent on the actual refresh interval (instead of some hardcoded value) to have it configurable?

It simplifies code and reduce efforts plus session stats are now only used in graphs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It simplifies code and reduce efforts plus session stats are now only used in graphs.

Personally, I've never even changed "refresh interval". But apparently it might make sense for someone to make the refresh less frequent? So, doesn't it make the same sense to make all refresh stuff less frequent for the same reason?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

session stats are now only used in graphs.

Only there? Really?
Then couldn't it make sense to make it available on demand, instead of constantly keep it refreshed at the app core level?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I've never even changed "refresh interval". But apparently it might make sense for someone to make the refresh less frequent? So, doesn't it make the same sense to make all refresh stuff less frequent for the same reason?

It seems a bit difficult to make SpeedPlotView refresh Interval aware.

Then couldn't it make sense to make it available on demand, instead of constantly keep it refreshed at the app core level?

querying stats via libtorrent, is an async operation so we will need to use the signals anyway, it may cause confusion down the line when someone else will need stats.

@github-actions
Copy link

This PR is stale because it has been 60 days with no activity. This PR will be automatically closed within 7 days if there is no further activity.

@github-actions github-actions bot added the Stale label Aug 12, 2021
@github-actions
Copy link

This PR was closed because it has been stalled for some time with no activity.

@github-actions github-actions bot closed this Aug 20, 2021
@ghost
Copy link

ghost commented Jul 17, 2022

Useless bot closes important PRs but no one closes old stale issues -_-

@glassez
Copy link
Member

glassez commented Jul 17, 2022

Useless bot closes important PRs

It closes stale/inactive PRs, doesn't it?

no one closes old stale issues

Wasn't there an intention for the bot to close them? But then something went wrong. Or, as always, there was no agreement on what and when should be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
GUI GUI-related issues/changes Stale
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants