Remaining time of sync estimate [patch]

(Adam Sjøgren) #1


I was just missing having an indication of how long the sync would take to finish - I get GiB remaining and MiB/s transferred, but I’d like an estimate of how long time remains, so I don’t have to do the calculation myself.

There is an open issue on this: #3698.

There hasn’t been any activity on it for a while, so I took a stab at it.

I could not make the code from the repo work (lots of fields in the GUI showed up with {}'s), so I worked on the version packaged in Debian unstable.

I know there probably should be a lot more factors incorporated in making a good estimate, but here is my working first version, which just takes the bytes remaining to be synced and divides by the current maximum transfer rate:

Index: syncthing-0.14.52+ds1/gui/default/index.html
--- syncthing-0.14.52+ds1.orig/gui/default/index.html
+++ syncthing-0.14.52+ds1/gui/default/index.html
@@ -634,7 +634,7 @@
                 <span ng-switch="deviceStatus(deviceCfg)" class="pull-right text-{{deviceClass(deviceCfg)}}">
                   <span ng-switch-when="insync"><span class="hidden-xs" translate>Up to Date</span><span class="visible-xs">&#9724;</span></span>
                   <span ng-switch-when="syncing">
-                    <span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.deviceID]._total | percent}}, {{completion[deviceCfg.deviceID]._needBytes | binary}}B)
+                    <span class="hidden-xs" translate>Syncing</span> ({{completion[deviceCfg.deviceID]._total | percent}}, {{completion[deviceCfg.deviceID]._needBytes | binary}}B, {{syncETA(deviceCfg.deviceID) | duration}})
                   <span ng-switch-when="paused"><span class="hidden-xs" translate>Paused</span><span class="visible-xs">&#9724;</span></span>
                   <span ng-switch-when="disconnected"><span class="hidden-xs" translate>Disconnected</span><span class="visible-xs">&#9724;</span></span>
Index: syncthing-0.14.52+ds1/gui/default/syncthing/core/syncthingController.js
--- syncthing-0.14.52+ds1.orig/gui/default/syncthing/core/syncthingController.js
+++ syncthing-0.14.52+ds1/gui/default/syncthing/core/syncthingController.js
@@ -813,6 +813,16 @@ angular.module('syncthing.core')
             return bytes;
+        $scope.syncETA = function (deviceID) {
+            // Remaining sync bytes divided by max of Download rate and Upload rate ~ ETA:
+            var bytes = $scope.completion[deviceID]._needBytes;
+            var rate = Math.max($scope.connections[deviceID].inbps, $scope.connections[deviceID].outbps);
+            if (rate == 0) {
+                return "";
+            }
+            return Math.floor(bytes / rate);
+        };
         $scope.scanPercentage = function (folder) {
             if (!$scope.scanProgress[folder]) {
                 return undefined;

I hope it can be useful to someone, or perhaps a starting point.

The patch against master can be pulled from

(uok) #2

I think a rough estimate is just fine.
Some time ago there was an idea for a multiline header which I really liked.

(Catfriend1) #3

I’m all pro this:-).

(uok) #4

Some thoughts on the estimated time:
I think the majority of people do not sync large amounts of data in both directions, e.g. usually one device adds new files and it is synced to other device(s).

Speed data
I would use only inbps for the folders, as this it what concerns users the most (e.g. how long do I have to wait before download is finished/can turn off computer?)

Folder ETA
Folder A downloads from device X with 100 KB/s
Folder B downloads from device Y with 1 MB/s
So my device gets total 1.1 MB/s but the estimation for folder A would be off (while both are downloading) if ETA is based on totalspeed.

Make funktion for ETA based on folder
step 1: function - read shared devices for folder and find current max(inbps) of these devices
output: functionETA (outofsyncfilesoffolder / maxinbps)

Devices ETA
Maybe we could also do the same for devices
output: functionETA (outofsyncfilesofdevice / deviceoutbps)

I don’t want to overcomplicate things but I think this should give a good ETA for most use cases. The pieces are already in the JS, so we only need to decide/pick which ones to use.

@asjo please move this code to github and create a PR so we can comment and test

(Jakob Borg) #5

A good estimate is much more complicated. Multiple folders might be syncing; the distribution of incoming bandwidth between them is something you can’t know from the javascript side. A folder might have 1 TB of out of sync data, but only a few blocks of it need to be downloaded. Another device might be out of sync and downloading from us, but also downloading from someone else. Etc.

Any “easy” calculation you use will be fine in some cases and wildly incorrect in others. It’s not clear to me that having that is better than not having it, as we will then have to handle the corner cases of “Syncthing said it would take 1 min, for over an hour!” or “Syncthing said it would take an hour, then it was suddenly done!” when people complain.

(uok) #6

That’s why I want to use only shared devices for a specific folder calculation. If folder A is only connected to device X then this inbps is the only one relevant.

I don’t think it matters so much. Once the out of sync amount changes the ETA updates anyways.

yeah, I guess this it what ETA means. and if the cleaning lady unplugs the router we show an infinity sign :slight_smile: But I think we are good as most most users only have a few folders and devices

(Adam Sjøgren) #7

I don’t have a Microsoft GitHub account.

Feel free to pull from my git repository or use the patch posted here, or ignore it, as you wish.

It solves my problem, which, I know, doesn’t cover all the cases.

(Catfriend1) #8

I guess you need to go into PR and can’t skip the review happening there if you wish to contribute.

(uok) #9

I created a PR for this issue #899