Repository: syncthing/syncthing
File: gui/default/syncthing/core/syncthingController.js (JavaScript)

Code before:
                    $scope.completion[device] = {};
                }
                $scope.completion[device][folder] = data;
                recalcCompletion(device);
            }).error($scope.emitHTTPError);
        }

        function refreshConnectionStats() {
            $http.get(urlbase + '/system/connections').success(function (data) {
                var now = Date.now(),
                    td = (now - prevDate) / 1000,
                    id;

                prevDate = now;

                try {
                    data.total.inbps = Math.max(0, (data.total.inBytesTotal - $scope.connectionsTotal.inBytesTotal) / td);
                    data.total.outbps = Math.max(0, (data.total.outBytesTotal - $scope.connectionsTotal.outBytesTotal) / td);
                } catch (e) {
                    data.total.inbps = 0;
                    data.total.outbps = 0;
                }
                $scope.connectionsTotal = data.total;

                data = data.connections;
                $scope.recentRemoteAddressCache = {};
                for (id in data) {
                    if (!data.hasOwnProperty(id)) {
                        continue;
                    }
                    if (!(id in $scope.idToRemoteAddress)) {
                        $scope.idToRemoteAddress[id] = "";
                    }
                    var port = $scope.findDevice(id).remoteAddressPort.toString();
                    var isNotRelayConnection = !data[id].type.includes("relay");
                    if ($scope.showRemoteAddress && isNotRelayConnection && port !== "0") {
                        var newAddress = "http://" + replaceAddressPort(data[id].address, port);
                        if ($scope.probeAddress(newAddress)) {
                            $scope.idToRemoteAddress[id] = newAddress;
                        }
                    }
                    try {
                        data[id].inbps = Math.max(0, (data[id].inBytesTotal - $scope.connections[id].inBytesTotal) / td);
                        data[id].outbps = Math.max(0, (data[id].outBytesTotal - $scope.connections[id].outBytesTotal) / td);
                    } catch (e) {
                        data[id].inbps = 0;
                        data[id].outbps = 0;
                    }
                }
                $scope.connections = data;
                console.log("refreshConnections", data);

Review comment (performance):
This variable doesn't need to be on the scope.

I was more imagining along the lines of (pseudo code missing parts):

```
var oldCache = $scope.remoteAddressCache;
var newCache = {};
for (id in data) {
    if ($scope.showRemoteAddress && isNotRelayConnection && port !== "0") {
    var newAddress = "http://" + replaceAddressPort(data[id].address, port);
    if (newAddress in oldCache) {
        newCache = oldCache[newAddress];
    } else {
        newCache[newAddress] = $scope.probeAddress(newAddress);
    }
    if (newCache[newAddress] === true) {
        $scope.idToRemoteAddress[id] = newAddress;
    } else {
        $scope.idToRemoteAddress[id] = "";
    }
}
$scope.remoteAddressCache = newCache;
```

This way probeAddress suits a single responsibility principle better (as it just probes, and not "check cache and maybe probe").



Code after:
                $scope.completion[device][folder] = data;
                recalcCompletion(device);
            }).error($scope.emitHTTPError);
        }

        function refreshConnectionStats() {
            $http.get(urlbase + '/system/connections').success(function (data) {
                var now = Date.now(),
                    td = (now - prevDate) / 1000,
                    id;

                prevDate = now;

                try {
                    data.total.inbps = Math.max(0, (data.total.inBytesTotal - $scope.connectionsTotal.inBytesTotal) / td);
                    data.total.outbps = Math.max(0, (data.total.outBytesTotal - $scope.connectionsTotal.outBytesTotal) / td);
                } catch (e) {
                    data.total.inbps = 0;
                    data.total.outbps = 0;
                }
                $scope.connectionsTotal = data.total;

                data = data.connections;
                for (id in data) {
                    if (!data.hasOwnProperty(id)) {
                        continue;
                    }
                    try {
                        data[id].inbps = Math.max(0, (data[id].inBytesTotal - $scope.connections[id].inBytesTotal) / td);
                        data[id].outbps = Math.max(0, (data[id].outBytesTotal - $scope.connections[id].outBytesTotal) / td);
                    } catch (e) {
                        data[id].inbps = 0;
                        data[id].outbps = 0;
                    }
                }
                $scope.connections = data;
                console.log("refreshConnections", data);

                refreshRemoteGUI(data);
            }).error($scope.emitHTTPError);
        }

        function refreshRemoteGUI(connections) {
            if (!$scope.showRemoteGUI) {
                $scope.idToRemoteGUI = {}
                return
            }
            var newCache = {};
            for (var id in connections) {
                if (!(id in $scope.devices)) {
                    // Avoid errors when called before first updateLocalConfig()