From 94c52e3a77bb76888eb9860adcdf48dbd279d438 Mon Sep 17 00:00:00 2001 From: AudriusButkevicius Date: Wed, 26 Aug 2015 23:49:06 +0100 Subject: [PATCH] Add scan percentages (fixes #1030) --- Godeps/Godeps.json | 2 +- .../github.com/syncthing/protocol/message.go | 1 + cmd/stfileinfo/main.go | 2 +- gui/index.html | 11 +- gui/syncthing/core/eventService.js | 1 + gui/syncthing/core/syncthingController.js | 24 +++++ lib/auto/gui.files.go | 8 +- lib/config/config.go | 29 ++--- lib/events/events.go | 3 + lib/model/model.go | 26 ++--- lib/model/rwfolder.go | 2 +- lib/model/rwfolder_test.go | 2 +- lib/scanner/blockqueue.go | 41 +++---- lib/scanner/blocks.go | 7 +- lib/scanner/blocks_test.go | 6 +- lib/scanner/walk.go | 102 +++++++++++++++--- lib/scanner/walk_test.go | 7 +- 17 files changed, 202 insertions(+), 72 deletions(-) diff --git a/Godeps/Godeps.json b/Godeps/Godeps.json index 9ca4aafc4..d82671f84 100644 --- a/Godeps/Godeps.json +++ b/Godeps/Godeps.json @@ -39,7 +39,7 @@ }, { "ImportPath": "github.com/syncthing/protocol", - "Rev": "388a29bbe21d8772ee4c29f4520aa8040309607d" + "Rev": "68c5dcd83d9be8f28ae59e951a87cdcf01c6f5cb" }, { "ImportPath": "github.com/syncthing/relaysrv/client", diff --git a/Godeps/_workspace/src/github.com/syncthing/protocol/message.go b/Godeps/_workspace/src/github.com/syncthing/protocol/message.go index 0cfeaa381..2a37136b5 100644 --- a/Godeps/_workspace/src/github.com/syncthing/protocol/message.go +++ b/Godeps/_workspace/src/github.com/syncthing/protocol/message.go @@ -20,6 +20,7 @@ type FileInfo struct { Modified int64 Version Vector LocalVersion int64 + CachedSize int64 // noencode (cache only) Blocks []BlockInfo // max:1000000 } diff --git a/cmd/stfileinfo/main.go b/cmd/stfileinfo/main.go index 6d5fed042..e663dc76d 100644 --- a/cmd/stfileinfo/main.go +++ b/cmd/stfileinfo/main.go @@ -68,7 +68,7 @@ func main() { if *standardBlocks || blockSize < protocol.BlockSize { blockSize = protocol.BlockSize } - bs, err := scanner.Blocks(fd, blockSize, fi.Size()) + bs, err := scanner.Blocks(fd, blockSize, fi.Size(), nil) if err != nil { log.Fatal(err) } diff --git a/gui/index.html b/gui/index.html index 7cc8b567d..47c68f805 100755 --- a/gui/index.html +++ b/gui/index.html @@ -195,13 +195,20 @@
+

{{folder.id}} - + + + + + @@ -445,7 +452,7 @@ - + Address Relayed via diff --git a/gui/syncthing/core/eventService.js b/gui/syncthing/core/eventService.js index c2a0a1a85..f14a4e7ca 100644 --- a/gui/syncthing/core/eventService.js +++ b/gui/syncthing/core/eventService.js @@ -78,6 +78,7 @@ angular.module('syncthing.core') STARTUP_COMPLETED: 'StartupCompleted', // Emitted exactly once, when initialization is complete and Syncthing is ready to start exchanging data with other devices STATE_CHANGED: 'StateChanged', // Emitted when a folder changes state FOLDER_ERRORS: 'FolderErrors', // Emitted when a folder has errors preventing a full sync + FOLDER_SCAN_PROGRESS: 'FolderScanProgress', // Emitted every ScanProgressIntervalS seconds, indicating how far into the scan it is at. start: function() { $http.get(urlbase + '/events?limit=1') diff --git a/gui/syncthing/core/syncthingController.js b/gui/syncthing/core/syncthingController.js index a083948f1..00234d0c8 100755 --- a/gui/syncthing/core/syncthingController.js +++ b/gui/syncthing/core/syncthingController.js @@ -48,6 +48,7 @@ angular.module('syncthing.core') $scope.failedCurrentPage = 1; $scope.failedCurrentFolder = undefined; $scope.failedPageSize = 10; + $scope.scanProgress = {}; $scope.localStateTotal = { bytes: 0, @@ -163,6 +164,12 @@ angular.module('syncthing.core') if (data.to === 'syncing') { $scope.failed[data.folder] = []; } + + // If a folder has started scanning, then any scan progress is + // also obsolete. + if (data.to === 'scanning') { + delete $scope.scanProgress[data.folder]; + } } }); @@ -310,6 +317,15 @@ angular.module('syncthing.core') $scope.failed[data.folder] = data.errors; }); + $scope.$on(Events.FOLDER_SCAN_PROGRESS, function (event, arg) { + var data = arg.data; + $scope.scanProgress[data.folder] = { + current: data.current, + total: data.total + }; + console.log("FolderScanProgress", data); + }); + $scope.emitHTTPError = function (data, status, headers, config) { $scope.$emit('HTTPError', {data: data, status: status, headers: headers, config: config}); }; @@ -634,6 +650,14 @@ angular.module('syncthing.core') return Math.floor(pct); }; + $scope.scanPercentage = function (folder) { + if (!$scope.scanProgress[folder]) { + return undefined; + } + var pct = 100 * $scope.scanProgress[folder].current / $scope.scanProgress[folder].total; + return Math.floor(pct); + } + $scope.deviceStatus = function (deviceCfg) { if ($scope.deviceFolders(deviceCfg).length === 0) { return 'unused'; diff --git a/lib/auto/gui.files.go b/lib/auto/gui.files.go index 223bc2c69..fdb73af6e 100644 --- a/lib/auto/gui.files.go +++ b/lib/auto/gui.files.go @@ -5,7 +5,7 @@ import ( ) const ( - AssetsBuildDate = "Tue, 25 Aug 2015 13:40:21 GMT" + AssetsBuildDate = "Thu, 27 Aug 2015 18:20:39 GMT" ) func Assets() map[string][]byte { @@ -50,7 +50,7 @@ func Assets() map[string][]byte { assets["assets/lang/lang-zh-TW.json"], _ = base64.StdEncoding.DecodeString("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") assets["assets/lang/prettyprint.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1xSUY7TMBD95xRWvrISuQASEiQsCxSVKpuF79nGm5g442hst9oijsNJuBgzdtSW/eq892bGb15zAFIWcNiRDuF5IYNBvVW/iseheFPU0Q5ABrB4XeyBiQYC2BW+O4DVuDdXvCq/rxzeSI8X6aT3I4NeM7jTNKdxbQWR1pMAZHCLgzV+TLC6qy+MKh/QBN2rjcGhd7Ns1rL5fgFcJ3x1e39hVMmFSRaeDNMfDa6NTySQ2GJGVfP+TKiyAYQeZGyMTH+KeL7eBCY+85EZ/pSjvwA/p71mPLlq0zK1caQlhvQri6zMfTVhjOwsjeIjM1tHRz0woWo3zX//WBEkkg8xJGuI/3Vtn9GRl6wW6dq5NaolVHWbCApxiGxGlTXBydibrO66F2quIenkqvYb662bkztVrlUSJYI2ep9t+4Pke9R9fjhIkF2kKcM4MXyYiFPP7aexarby748G07tSpL2sdD+ulQ7MUb6X36/+AQAA//8BAAD//5YJ/N+MAgAA") assets["assets/lang/valid-langs.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/yTMvQ6CMBTF8d2nIJ29j2CiEOOgUVNJHIxDgQqVppC2dPDpvacsv38/kpOUL5Kyprso14diV7xE04utaFVmz3/atSbfAtNpRlvgMnQq0ZCh44P7McBnqDpwh4UxkfliaZzoLLkWL64BWHRYnHGaI5Vy7b3m+onkDcVOSEzE/DIyv4Gq69r6Kd6bPwAAAP//AQAA//8bXi5E0gAAAA==") - assets["index.html"], _ = base64.StdEncoding.DecodeString("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") + assets["index.html"], _ = base64.StdEncoding.DecodeString("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") assets["modal.html"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/3RST0/cPhC9/z7F/HLogkQ2gDjRXaoWqVIlKiHBpceJPUlcHDuyJ9BtlO/eibNNYbUcEv97783Mm9lo8wzKYozbrPUaLVSoKQPG0jhNv7ZZfpGBq3NkDrlGxrxE9aSD77bZMAjVR4JPwKEnuIZVZGSjVjCOB6wn2pUeg06sL95bQneS2KcT+OY/gM3/eS5LUcCt73bB1A3Dye0pXJ5fXMFjQ/Cwc4ob42r43HPjQ1wn+Mx5bEyEB98HRcLXBF99aEHuYl/+JMXAHlhEmEIbwVfp8N3/NtYi3PelNWoWujOKXKQzeF7D5fp8Dd8qQFCS0sK6v4MXjOA8gzaRgyl7Jg0vhhsBSMzKWDqb5X74HhQ68CWjkcURIEPD3F0XRTvHX/tQF6JaSLxiKirPkyGHzcm1QevrZO3+fljNL7ZeXYPFUNNs5jG28o7J8f79GKIh6X4AtBR4/ufDMPW0j+O48ITZXL0lsmFLrwACiZ1ULYmaapsZCZ39ZVQoQya60+Wkuikm6GvuMCS9cfwXsGiulrQLyfv9Gkqvd8khDuiisr2m95n7/NIgZm91Ku9lVl4XLV1m74B3HW2z+bBwSnYgX66pwt5y2sc2gzT8MiStWZSP2PTGGTYtxcWWD66M3ccZliqyyHRzOyV8aNymmJM6Uu6y3W/2yx8AAAD//wEAAP//qvxG6f8DAAA=") assets["syncthing/app.js"], _ = base64.StdEncoding.DecodeString("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") assets["syncthing/core/aboutModalDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1SOMQ7CMAxF954im1upSnc6cQBG2ENqWktOglwHhFDvTgpSgT/+/yw/F8fMTmxIQ2asYX5ErxPF0fokCE1lSuxAgl7pVgB3TlkPaXAMrbnkQlOKpm7M842uEdQs8af4lLMKed0Z2EP7NymGKzvFo3BZN4NuNei+/06EdztpYNiul75amr56AQAA//8BAAD//xLf4CHFAAAA") @@ -59,7 +59,7 @@ func Assets() map[string][]byte { assets["syncthing/core/basenameFilter.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/2yOTU7DMBCF9z3F0I1tCRx1XXySpgvTjBNLziTyDxIiuTuJg4QNvNVI75tvRlOfnPZynLrkkLPwQY84WOrlY/LIxAm2SGNdRM/Zmw5IekT2DCZtoJ0IuIDPTO3xGJOnorQ0p1gSe6z5LkApBYk6NJawExVU6M7na1W9aw+z9jGAguyRYXY28ubWNm17b8T1z7mng1+WY1E6pD4O8AqX388Vd7O7dq2nf7isvFXiF7jcfzbXY1y3x74AAAD//wEAAP//1ZQ6AXEBAAA=") assets["syncthing/core/binaryFilter.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/6SSTU7DMBCF9z3F7GxDZUrFLjJLWKAewsTjdiR3jFxbokK5O0lTJIMa/jKbRJrvPX+LsbwtwSa9j64ElOJw5DbviLe6jQmFWkA/2lPImKR4JrbpKJbgS49RZJAK3k7MMAlzSVwtiV9KrolhyJ8XYIyBwg49MbqvWFUoViCaT8tuovEeblfrO7iqP5eKR/rGXMCbKYtTRuf4QK/opMOW9jYcxoeXsFYKrkHAI/1H9beOM+U2f5P70WqmztP3Oueujc07nWJ/KB/3NGSrZDf+dqpZvAMAAP//AQAA///Yhw40zwIAAA==") assets["syncthing/core/durationFilter.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/3RUTW/aQBS8+1dMV6rsAAE7iVBlQnpoOeTQ5JBjFFUbvMYuthftB21K/N/7FnAwBS+S9TDzZmbnPTHq9TCX1VooA15KWxnIFFrQu0TDSGij8mqBVKqSG7AEGUpoht+5yaQ1+CuUxJoXVmgPPayUmOc6lxVKqw1eBWQlHKWf+AP4mXuU7qH9IBEpt4W5cH2zP7xcFSJ29WYTXUXhVRiG1++JVdwQXV3DncvLO0Q3YZggGme4CUtc666WmJWM2k5auvHZCX6P/R/THIe9jTKv1xt5vFrYgqthKRNbiMDXb9XcZJTdcC6V8OmWdIZpXhihAr8hpChSS0CXWHCBjddQ+1aLbfhz40+8j9drrvA0+/b48P3p5/0DptiwhMX4MibHA5C7GNfjbVlSOaYCTFMV1ZMPDiWMVVVLN69W1gwOs2v7aESV0DQrEmRscvRjniL41NnqzmEnps7McXt9TOacEGzFlRb3lWmsReHFcRvtIwLna0k9rUTO6TuYI92RjQ7g5+UL3kHUGI3wg5tsmBZSKu+Ewd3R4I6gZ+h3kW7T6dMF6dMnuT6WkxNofZ66FdAUy26N7dj2Ul+bIga7jViHHkRBa3Seb5f15ymOAjlnuvvb3hN7niklVUyctOx0GwOr+UIMuv8PnOPH118EHS7Fmw7aI+yDvbTWZL+6Na3APwAAAP//AQAA///R6NJhrwQAAA==") - assets["syncthing/core/eventService.js"], _ = base64.StdEncoding.DecodeString("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") + assets["syncthing/core/eventService.js"], _ = base64.StdEncoding.DecodeString("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") assets["syncthing/core/httpErrorDialogDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1yOwcrCMBCE732K3LaFkt7/nn7QR9B7SNd2YZOU7UYR6bubKhR1jjOzO5+LY2YnNqQhM9aw3KPXieJofRKEpjJFdiBBr3QthUl1PookOZDjNEJrLrmcUIqmbszj1d8kqFnih/E2FxXy+mfgH9qvSDHM7BRPwiXdMboNo/sZPRPe7KSBYX+x9tXa9NUTAAD//wEAAP//F1ZQpc8AAAA=") assets["syncthing/core/httpErrorDialogView.html"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/0yQsW7DMAxE5/orCC2ZmvyA7aXoXqBfwMgXW4AsqSQNJEjz75VcFM0kvLvDiWS/5okjhWlwi1l5F8niSI1t08FNnGZUDj6nweHqI69sIadXH8RHOLJgEYO73w9vOSX4ZtLecqBvMuGkkQ2Phxu7l778KxWJPm/J2xLSTAqsSpbpDMK1QAKSbwZTkXyOWNvrodrEW96EBF8b1I70EcGKyheBLmQLqPAMyi1TVxF7+ihcfgN/pRANanqs053K2PWn/SBj9wMAAP//AQAA//+4f+ClGQEAAA==") assets["syncthing/core/identiconDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/5xVTVPbMBC951dsZwp2GkcOdHpJ6s4wDMxwgENz6IEyHVdWYk0VKSPLcSnkv3clJ8F2FL50wUj79r2V3m5SOS9FqslCZaVgYVDcS2pyLueEKs2Cfg9wkYxrRg1fYQDPmDScKhlEcBt8rLjMVIXfsxKBXEkIN3t9eHBgu1aphmI1v5lCAkFuzHIcx1VVkeozUXoen45GoxjPg0lvB9nlu9oShqtUlCyCgv9jzeQNAkyfKVouEEGoZqlhF4LZ/26moeOPILA8/ck+OlelyC65EN+x1DODqZ5K0qqKgCrRpbVLM1NqCR+2dZNlqgt2JU2tl9A81ecqY2fGpoGBzQOf6ioiOBn14QhOO4LWh/Rdc62Vfq9Cy2nZ4PjYqUiSBBY8ywQ7R+RLChaOGyMvlW5xP0/rSIeObwgnL9Y5e/sLWJj152te38bZ5/eopYYUDHmN5r9Lg1b/i7YO69eyp1PnuwEER13/HMDfW7x983fiK56ZHHNswW/B5ozPc+MD76Hxaki6XDKZnedcZKFFvOxHG+XZVdX+Jl6hz00b3/lTW8kdrVZnu0gq0qLAGhtDqSPcmS+p/zw+wpf26e5uEuzDEcQurh2yk4kx16nJCWVc1I0UY9vWlm4h+AzqzvdbFQ8wVT0ajJpiLXIe9olmS5FSFsa3P3/8uos5FuV9rBn2nvNUAqOJvW74WquGwUC3h+4ezLV84+JdT36D4ckEhsMDvdWsqjsin5ryOaSj92A8xfkJmzPv9ZQ+2uYEc1PL00vNtT546j/Z323vrHsd+9UDcjV/ktEI2Rw/dDAFWoaaMQQXQdT2OlVLNj5kOgQkQVtNGy64/DNuTFyXLgJWj9AI0m3fFb6r34RtBkkoWdX44XapSN0U3cnSa3+t7zDgPwAAAP//AQAA//9afsjulQgAAA==") @@ -79,7 +79,7 @@ func Assets() map[string][]byte { assets["syncthing/core/selectOnClickDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/3SQQWvEIBCF7/srPBRiIEjPXXooe2+hPZYeRKeprJkpo2YpJf+9atLdJWzeSZ/z+Z5q7JPXrAayyYNswg+a+OWwV4YYmnYnspR1DCa6sQyAz8sXPHhnjk0nPlMGHKGQdyeHlk6t+K1QEUNMjFdGkXd4fLjigqFv6ES+dwCMndAxcmhXUNEyoQhlY1bx8hZQNGoWc+cS9iiWlqqH+PZvy3a/yXL+IcicJZNqumHQEV6LvcVVRs2pz2ThQBgzGuTygvf7jw3y3FQxDDTCk/c1KWxFXQBt7Vyqpt8Yn1bedN5N+105/AMAAP//AQAA//+SF+4JDAIAAA==") assets["syncthing/core/shutdownDialogDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1SOwQqDQAxE737F3qIg672eCv2F9r6sqQZitsRspRT/vdqC1DnOTDIvSJ85qB9TlxlLmF4SbSDpfUyKUBVule9IMRo9t8KQrUuzXChw6qF297xeUBJXVu79rW9StKzyZ/zMyZSinRycoT5EhuODg+FVeU13imajaI6bN8LZDzYy7B+WtliqtvgAAAD//wEAAP//3qFOo80AAAA=") assets["syncthing/core/shutdownDialogView.html"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/0TOTaqDMBAH8PXzFMNsXL16gZhNj+AJ0jjWQJwJzgQp1ru3lkK3P/h/uEXGkCGNPepcbZSNEdSCVX1LjZFUEVIU7rHIRuu/TBOCJcvU4763wzcFV1lKJqMWnmBrYM3B6DjQN3+u/MQPD442J77DHBRuRAznMpwlF9cV37juc8o3LwAAAP//AQAA//99X8KxnQAAAA==") - assets["syncthing/core/syncthingController.js"], _ = base64.StdEncoding.DecodeString("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") + assets["syncthing/core/syncthingController.js"], _ = base64.StdEncoding.DecodeString("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") assets["syncthing/core/uniqueFolderDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/7SSwW4yMQyE7zyFD7+0IK3CHc5/b1V74h5tvKzVkIDtQFHFuzdhUaGwtJWqzgVp4vkYW2vDMnnLZhVd8jiuZB8a7SgsTRMZq8kIsowjxkZpmwdSoE3Ch+gdclVDm/I8xQDjCbwdh4sYNXG4MHpzkzJnBlVYPkaHvqo/vXsKL7MLoDRxjTWgX9VgVVlqaJT95ApbVHzzb21ZkMWkIB21Oj6jtoS7hfUJh8JF1J7+z6Ajzev/fyUpv/cCRdMp7BCki8m7UClsrSdnFe8G+pqCuiiTpPubcyrnjvNBwCFfQvCiaXsMiemsPO3CM2ePM/K86zfdtUPoGYBlWwHrGa3b/6J/a3PHrxf4aScS6OF/dM5B9/ThftzwNnu44p05h/moPL4DAAD//wEAAP//r65WJ1IDAAA=") assets["syncthing/core/upgradingDialogDirective.js"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1yOwQrCMBBE7/2K3LaFkt7tSfAX9B7SNV3YJmW7UUT676YKRZ3jzNudcTFkdmKnNGTGGpZH9DpSDNYnQWgqU2QHEvRKtwLkOYgbCnAixylAa665nFCKpm7M881vEtQs8cv4mIsKeT0YOEL7EylOMzvFs3BJ9xndNqP7K70Q3u2oE8P+Yu2rtemrFwAAAP//AQAA//99zQ2GzwAAAA==") assets["syncthing/core/upgradingDialogView.html"], _ = base64.StdEncoding.DecodeString("H4sIAAAJbogA/1zOTarDMAwE4PXLKYQ2WSW5gO0zPCg9gHDcVODaxlIIJc3dm5b+QLfDN8yYSx4pAo8W5zJVGjlNCKKks1jkdMoI7HOySLXmpfNcfQzdXBCUNQaL69oe380WbqCVkkTSsG3omj9TnJFC6Zu7wzV5Pe8cWOCz2pvh4Rz88v8YSAIsxPoifb/j4hozPN+75g4AAP//AQAA///kaeW6xgAAAA==") diff --git a/lib/config/config.go b/lib/config/config.go index 8d973b5f1..5e82fbc4c 100644 --- a/lib/config/config.go +++ b/lib/config/config.go @@ -68,20 +68,21 @@ func (cfg Configuration) Copy() Configuration { } type FolderConfiguration struct { - ID string `xml:"id,attr" json:"id"` - RawPath string `xml:"path,attr" json:"path"` - Devices []FolderDeviceConfiguration `xml:"device" json:"devices"` - ReadOnly bool `xml:"ro,attr" json:"readOnly"` - RescanIntervalS int `xml:"rescanIntervalS,attr" json:"rescanIntervalS"` - IgnorePerms bool `xml:"ignorePerms,attr" json:"ignorePerms"` - AutoNormalize bool `xml:"autoNormalize,attr" json:"autoNormalize"` - MinDiskFreePct int `xml:"minDiskFreePct" json:"minDiskFreePct"` - Versioning VersioningConfiguration `xml:"versioning" json:"versioning"` - Copiers int `xml:"copiers" json:"copiers"` // This defines how many files are handled concurrently. - Pullers int `xml:"pullers" json:"pullers"` // Defines how many blocks are fetched at the same time, possibly between separate copier routines. - Hashers int `xml:"hashers" json:"hashers"` // Less than one sets the value to the number of cores. These are CPU bound due to hashing. - Order PullOrder `xml:"order" json:"order"` - IgnoreDelete bool `xml:"ignoreDelete" json:"ignoreDelete"` + ID string `xml:"id,attr" json:"id"` + RawPath string `xml:"path,attr" json:"path"` + Devices []FolderDeviceConfiguration `xml:"device" json:"devices"` + ReadOnly bool `xml:"ro,attr" json:"readOnly"` + RescanIntervalS int `xml:"rescanIntervalS,attr" json:"rescanIntervalS"` + IgnorePerms bool `xml:"ignorePerms,attr" json:"ignorePerms"` + AutoNormalize bool `xml:"autoNormalize,attr" json:"autoNormalize"` + MinDiskFreePct int `xml:"minDiskFreePct" json:"minDiskFreePct"` + Versioning VersioningConfiguration `xml:"versioning" json:"versioning"` + Copiers int `xml:"copiers" json:"copiers"` // This defines how many files are handled concurrently. + Pullers int `xml:"pullers" json:"pullers"` // Defines how many blocks are fetched at the same time, possibly between separate copier routines. + Hashers int `xml:"hashers" json:"hashers"` // Less than one sets the value to the number of cores. These are CPU bound due to hashing. + Order PullOrder `xml:"order" json:"order"` + IgnoreDelete bool `xml:"ignoreDelete" json:"ignoreDelete"` + ScanProgressIntervalS int `xml:"scanProgressInterval" json:"scanProgressInterval"` // Set to a negative value to disable. Value of 0 will get replaced with value of 2 (default value) Invalid string `xml:"-" json:"invalid"` // Set at runtime when there is an error, not saved } diff --git a/lib/events/events.go b/lib/events/events.go index e26b830d5..effd8dfb7 100644 --- a/lib/events/events.go +++ b/lib/events/events.go @@ -38,6 +38,7 @@ const ( FolderSummary FolderCompletion FolderErrors + FolderScanProgress AllEvents = (1 << iota) - 1 ) @@ -84,6 +85,8 @@ func (t EventType) String() string { return "DevicePaused" case DeviceResumed: return "DeviceResumed" + case FolderScanProgress: + return "FolderScanProgress" default: return "Unknown" } diff --git a/lib/model/model.go b/lib/model/model.go index df46e1efe..dac0019c3 100644 --- a/lib/model/model.go +++ b/lib/model/model.go @@ -1297,18 +1297,20 @@ nextSub: subs = unifySubs w := &scanner.Walker{ - Dir: folderCfg.Path(), - Subs: subs, - Matcher: ignores, - BlockSize: protocol.BlockSize, - TempNamer: defTempNamer, - TempLifetime: time.Duration(m.cfg.Options().KeepTemporariesH) * time.Hour, - CurrentFiler: cFiler{m, folder}, - MtimeRepo: db.NewVirtualMtimeRepo(m.db, folderCfg.ID), - IgnorePerms: folderCfg.IgnorePerms, - AutoNormalize: folderCfg.AutoNormalize, - Hashers: m.numHashers(folder), - ShortID: m.shortID, + Folder: folderCfg.ID, + Dir: folderCfg.Path(), + Subs: subs, + Matcher: ignores, + BlockSize: protocol.BlockSize, + TempNamer: defTempNamer, + TempLifetime: time.Duration(m.cfg.Options().KeepTemporariesH) * time.Hour, + CurrentFiler: cFiler{m, folder}, + MtimeRepo: db.NewVirtualMtimeRepo(m.db, folderCfg.ID), + IgnorePerms: folderCfg.IgnorePerms, + AutoNormalize: folderCfg.AutoNormalize, + Hashers: m.numHashers(folder), + ShortID: m.shortID, + ProgressTickIntervalS: folderCfg.ScanProgressIntervalS, } runner.setState(FolderScanning) diff --git a/lib/model/rwfolder.go b/lib/model/rwfolder.go index 57b3bce94..ed48d4b45 100644 --- a/lib/model/rwfolder.go +++ b/lib/model/rwfolder.go @@ -989,7 +989,7 @@ func (p *rwFolder) handleFile(file protocol.FileInfo, copyChan chan<- copyBlocks // Check for an old temporary file which might have some blocks we could // reuse. - tempBlocks, err := scanner.HashFile(tempName, protocol.BlockSize) + tempBlocks, err := scanner.HashFile(tempName, protocol.BlockSize, 0, nil) if err == nil { // Check for any reusable blocks in the temp file tempCopyBlocks, _ := scanner.BlockDiff(tempBlocks, file.Blocks) diff --git a/lib/model/rwfolder_test.go b/lib/model/rwfolder_test.go index 083b5e978..b6369c8ca 100644 --- a/lib/model/rwfolder_test.go +++ b/lib/model/rwfolder_test.go @@ -241,7 +241,7 @@ func TestCopierFinder(t *testing.T) { } // Verify that the fetched blocks have actually been written to the temp file - blks, err := scanner.HashFile(tempFile, protocol.BlockSize) + blks, err := scanner.HashFile(tempFile, protocol.BlockSize, 0, nil) if err != nil { t.Log(err) } diff --git a/lib/scanner/blockqueue.go b/lib/scanner/blockqueue.go index 553aeec25..a7763403d 100644 --- a/lib/scanner/blockqueue.go +++ b/lib/scanner/blockqueue.go @@ -19,24 +19,27 @@ import ( // workers are used in parallel. The outbox will become closed when the inbox // is closed and all items handled. -func newParallelHasher(dir string, blockSize, workers int, outbox, inbox chan protocol.FileInfo) { +func newParallelHasher(dir string, blockSize, workers int, outbox, inbox chan protocol.FileInfo, counter *uint64, done chan struct{}) { wg := sync.NewWaitGroup() wg.Add(workers) for i := 0; i < workers; i++ { go func() { - hashFiles(dir, blockSize, outbox, inbox) + hashFiles(dir, blockSize, outbox, inbox, counter) wg.Done() }() } go func() { wg.Wait() + if done != nil { + close(done) + } close(outbox) }() } -func HashFile(path string, blockSize int) ([]protocol.BlockInfo, error) { +func HashFile(path string, blockSize int, sizeHint int64, counter *uint64) ([]protocol.BlockInfo, error) { fd, err := os.Open(path) if err != nil { if debug { @@ -44,27 +47,29 @@ func HashFile(path string, blockSize int) ([]protocol.BlockInfo, error) { } return []protocol.BlockInfo{}, err } - - fi, err := fd.Stat() - if err != nil { - fd.Close() - if debug { - l.Debugln("stat:", err) - } - return []protocol.BlockInfo{}, err - } defer fd.Close() - return Blocks(fd, blockSize, fi.Size()) + + if sizeHint == 0 { + fi, err := fd.Stat() + if err != nil { + if debug { + l.Debugln("stat:", err) + } + return []protocol.BlockInfo{}, err + } + sizeHint = fi.Size() + } + + return Blocks(fd, blockSize, sizeHint, counter) } -func hashFiles(dir string, blockSize int, outbox, inbox chan protocol.FileInfo) { +func hashFiles(dir string, blockSize int, outbox, inbox chan protocol.FileInfo, counter *uint64) { for f := range inbox { - if f.IsDirectory() || f.IsDeleted() || f.IsSymlink() { - outbox <- f - continue + if f.IsDirectory() || f.IsDeleted() { + panic("Bug. Asked to hash a directory or a deleted file.") } - blocks, err := HashFile(filepath.Join(dir, f.Name), blockSize) + blocks, err := HashFile(filepath.Join(dir, f.Name), blockSize, f.CachedSize, counter) if err != nil { if debug { l.Debugln("hash error:", f.Name, err) diff --git a/lib/scanner/blocks.go b/lib/scanner/blocks.go index bd191f238..b853b2aac 100644 --- a/lib/scanner/blocks.go +++ b/lib/scanner/blocks.go @@ -11,6 +11,7 @@ import ( "crypto/sha256" "fmt" "io" + "sync/atomic" "github.com/syncthing/protocol" ) @@ -18,7 +19,7 @@ import ( var SHA256OfNothing = []uint8{0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55} // Blocks returns the blockwise hash of the reader. -func Blocks(r io.Reader, blocksize int, sizehint int64) ([]protocol.BlockInfo, error) { +func Blocks(r io.Reader, blocksize int, sizehint int64, counter *uint64) ([]protocol.BlockInfo, error) { var blocks []protocol.BlockInfo if sizehint > 0 { blocks = make([]protocol.BlockInfo, 0, int(sizehint/int64(blocksize))) @@ -36,6 +37,10 @@ func Blocks(r io.Reader, blocksize int, sizehint int64) ([]protocol.BlockInfo, e break } + if counter != nil { + atomic.AddUint64(counter, uint64(n)) + } + b := protocol.BlockInfo{ Size: int32(n), Offset: offset, diff --git a/lib/scanner/blocks_test.go b/lib/scanner/blocks_test.go index abdd40fa0..a52101b7d 100644 --- a/lib/scanner/blocks_test.go +++ b/lib/scanner/blocks_test.go @@ -51,7 +51,7 @@ var blocksTestData = []struct { func TestBlocks(t *testing.T) { for _, test := range blocksTestData { buf := bytes.NewBuffer(test.data) - blocks, err := Blocks(buf, test.blocksize, 0) + blocks, err := Blocks(buf, test.blocksize, 0, nil) if err != nil { t.Fatal(err) @@ -105,8 +105,8 @@ var diffTestData = []struct { func TestDiff(t *testing.T) { for i, test := range diffTestData { - a, _ := Blocks(bytes.NewBufferString(test.a), test.s, 0) - b, _ := Blocks(bytes.NewBufferString(test.b), test.s, 0) + a, _ := Blocks(bytes.NewBufferString(test.a), test.s, 0, nil) + b, _ := Blocks(bytes.NewBufferString(test.b), test.s, 0, nil) _, d := BlockDiff(a, b) if len(d) != len(test.d) { t.Fatalf("Incorrect length for diff %d; %d != %d", i, len(d), len(test.d)) diff --git a/lib/scanner/walk.go b/lib/scanner/walk.go index 61dc88f9a..a4079b5f9 100644 --- a/lib/scanner/walk.go +++ b/lib/scanner/walk.go @@ -12,11 +12,13 @@ import ( "path/filepath" "runtime" "strings" + "sync/atomic" "time" "unicode/utf8" "github.com/syncthing/protocol" "github.com/syncthing/syncthing/lib/db" + "github.com/syncthing/syncthing/lib/events" "github.com/syncthing/syncthing/lib/ignore" "github.com/syncthing/syncthing/lib/osutil" "github.com/syncthing/syncthing/lib/symlinks" @@ -39,6 +41,8 @@ func init() { } type Walker struct { + // Folder for which the walker has been created + Folder string // Dir is the base directory for the walk Dir string // Limit walking to these paths within Dir, or no limit if Sub is empty @@ -66,6 +70,9 @@ type Walker struct { Hashers int // Our vector clock id ShortID uint64 + // Optional progress tick interval which defines how often FolderScanProgress + // events are emitted. Negative number means disabled. + ProgressTickIntervalS int } type TempNamer interface { @@ -92,12 +99,13 @@ func (w *Walker) Walk() (chan protocol.FileInfo, error) { return nil, err } - files := make(chan protocol.FileInfo) - hashedFiles := make(chan protocol.FileInfo) - newParallelHasher(w.Dir, w.BlockSize, w.Hashers, hashedFiles, files) + toHashChan := make(chan protocol.FileInfo) + finishedChan := make(chan protocol.FileInfo) + // A routine which walks the filesystem tree, and sends files which have + // been modified to the counter routine. go func() { - hashFiles := w.walkAndHashFiles(files, hashedFiles) + hashFiles := w.walkAndHashFiles(toHashChan, finishedChan) if len(w.Subs) == 0 { filepath.Walk(w.Dir, hashFiles) } else { @@ -105,10 +113,77 @@ func (w *Walker) Walk() (chan protocol.FileInfo, error) { filepath.Walk(filepath.Join(w.Dir, sub), hashFiles) } } - close(files) + close(toHashChan) }() - return hashedFiles, nil + // We're not required to emit scan progress events, just kick off hashers, + // and feed inputs directly from the walker. + if w.ProgressTickIntervalS < 0 { + newParallelHasher(w.Dir, w.BlockSize, w.Hashers, finishedChan, toHashChan, nil, nil) + return finishedChan, nil + } + + // Defaults to every 2 seconds. + if w.ProgressTickIntervalS == 0 { + w.ProgressTickIntervalS = 2 + } + + ticker := time.NewTicker(time.Duration(w.ProgressTickIntervalS) * time.Second) + + // We need to emit progress events, hence we create a routine which buffers + // the list of files to be hashed, counts the total number of + // bytes to hash, and once no more files need to be hashed (chan gets closed), + // start a routine which periodically emits FolderScanProgress events, + // until a stop signal is sent by the parallel hasher. + // Parallel hasher is stopped by this routine when we close the channel over + // which it receives the files we ask it to hash. + go func() { + var filesToHash []protocol.FileInfo + var total, progress uint64 + for file := range toHashChan { + filesToHash = append(filesToHash, file) + total += uint64(file.CachedSize) + } + + realToHashChan := make(chan protocol.FileInfo) + done := make(chan struct{}) + newParallelHasher(w.Dir, w.BlockSize, w.Hashers, finishedChan, realToHashChan, &progress, done) + + // A routine which actually emits the FolderScanProgress events + // every w.ProgressTicker ticks, until the hasher routines terminate. + go func() { + for { + select { + case <-done: + if debug { + l.Debugln("Walk progress done", w.Dir, w.Subs, w.BlockSize, w.Matcher) + } + ticker.Stop() + return + case <-ticker.C: + current := atomic.LoadUint64(&progress) + if debug { + l.Debugf("Walk %s %s current progress %d/%d (%d%%)", w.Dir, w.Subs, current, total, current*100/total) + } + events.Default.Log(events.FolderScanProgress, map[string]interface{}{ + "folder": w.Folder, + "current": current, + "total": total, + }) + } + } + }() + + for _, file := range filesToHash { + if debug { + l.Debugln("real to hash:", file.Name) + } + realToHashChan <- file + } + close(realToHashChan) + }() + + return finishedChan, nil } func (w *Walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath.WalkFunc { @@ -241,7 +316,7 @@ func (w *Walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath. return skip } - blocks, err := Blocks(strings.NewReader(target), w.BlockSize, 0) + blocks, err := Blocks(strings.NewReader(target), w.BlockSize, 0, nil) if err != nil { if debug { l.Debugln("hash link error:", p, err) @@ -272,10 +347,10 @@ func (w *Walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath. } if debug { - l.Debugln("symlink to hash:", p, f) + l.Debugln("symlink changedb:", p, f) } - fchan <- f + dchan <- f return skip } @@ -349,10 +424,11 @@ func (w *Walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath. } f := protocol.FileInfo{ - Name: rn, - Version: cf.Version.Update(w.ShortID), - Flags: flags, - Modified: mtime.Unix(), + Name: rn, + Version: cf.Version.Update(w.ShortID), + Flags: flags, + Modified: mtime.Unix(), + CachedSize: info.Size(), } if debug { l.Debugln("to hash:", p, f) diff --git a/lib/scanner/walk_test.go b/lib/scanner/walk_test.go index 0d9bbcb66..5fc5c1c5f 100644 --- a/lib/scanner/walk_test.go +++ b/lib/scanner/walk_test.go @@ -149,8 +149,9 @@ func TestVerify(t *testing.T) { // data should be an even multiple of blocksize long data := []byte("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut e") buf := bytes.NewBuffer(data) + var progress uint64 - blocks, err := Blocks(buf, blocksize, 0) + blocks, err := Blocks(buf, blocksize, 0, &progress) if err != nil { t.Fatal(err) } @@ -158,6 +159,10 @@ func TestVerify(t *testing.T) { t.Fatalf("Incorrect number of blocks %d != %d", len(blocks), exp) } + if uint64(len(data)) != progress { + t.Fatalf("Incorrect counter value %d != %d", len(data), progress) + } + buf = bytes.NewBuffer(data) err = Verify(buf, blocksize, blocks) t.Log(err)