Rakefiles: move retrying code from `scm.rb` to `hglib.rb`
authorJan Vrany <jan.vrany@fit.cvut.cz>
Wed, 24 Jul 2019 21:24:11 +0100
changeset 269 e6ccd5be9bcb
parent 268 da6c28844912
child 270 abb5268826c7
Rakefiles: move retrying code from `scm.rb` to `hglib.rb` This is a followup for previous commit dd183640f63e5d. Moving them to `hglib.rb` reduces code duplication and makes usage of the workaround more transparent.
rakelib/hglib.rb
rakelib/scm.rb
--- a/rakelib/hglib.rb	Wed Jul 24 10:02:21 2019 +0000
+++ b/rakelib/hglib.rb	Wed Jul 24 21:24:11 2019 +0100
@@ -428,6 +428,27 @@
       authconf
     end
 
+    # Return true, if given remote is known to be shaky, i.e., randomly failing.
+    # BitBucket is known to be very, very shaky recently (since summer 2919().
+    def shaky_remote?(remote)
+      remote_url = @config['paths'][remote] || remote
+      return remote_url =~ /bitbucket.org/
+    end
+
+    def pull1(remote = 'default', user: nil, pass: nil, rev: nil, bookmarks: nil)
+      hg('pull', remote, ssh: sshconf(remote), config: authconf(remote, user, pass), rev: rev, bookmark: bookmarks) do |status, stdout|
+        STDOUT.print stdout
+        case status.exitstatus
+          when 0
+            #nothing
+          when 1
+            raise Exception.new("Failed to 'pull' from #{remote} (update had unresolved conflicts)")
+          else
+            raise Exception.new("Failed to 'pull' from #{remote} (exit code #{status.exitstatus})")
+        end
+      end
+    end
+
     public
 
     def incoming(remote = 'default', user: nil, pass: nil, rev: nil)
@@ -444,15 +465,25 @@
     end
 
     def pull(remote = 'default', user: nil, pass: nil, rev: nil, bookmarks: nil)
-      hg('pull', remote, ssh: sshconf(remote), config: authconf(remote, user, pass), rev: rev, bookmark: bookmarks) do |status, stdout|
-        STDOUT.print stdout
-        case status.exitstatus
-          when 0
-            #nothing
-          when 1
-            raise Exception.new("Failed to 'pull' from #{remote} (update had unresolved conflicts)")
-          else
-            raise Exception.new("Failed to 'pull' from #{remote} (exit code #{status.exitstatus})")
+      if not shaky_remote?(remote)
+        pull1(remote, user: user, pass: pass, rev: rev, bookmarks: bookmarks)
+      else
+        # Remote is shaky, try to pull, if pull fails, wait some time and retry
+        # again. See #shaky_remote?()
+        begin
+          pull1(remote, user: user, pass: pass, rev: rev, bookmarks: bookmarks)
+        rescue Exception
+          delay = 30 + rand * 100
+          puts "Oops, remote is shaky, retrying after #{delay}"
+          sleep(delay)
+          begin
+            pull1(remote, user: user, pass: pass, rev: rev, bookmarks: bookmarks)
+          rescue Exception
+            delay = 30 + rand * 100
+            puts "Oops, remote is shaky, retrying after #{delay}"
+            sleep(delay)
+            pull1(remote, user: user, pass: pass, rev: rev, bookmarks: bookmarks)
+          end
         end
       end
     end
--- a/rakelib/scm.rb	Wed Jul 24 10:02:21 2019 +0000
+++ b/rakelib/scm.rb	Wed Jul 24 21:24:11 2019 +0100
@@ -153,21 +153,7 @@
         hg.paths = paths
       end
 
-      begin
-        hg.pull('canonical') if repository.canonical
-      rescue Exception
-        delay = 30 + rand * 100
-        info("Will retry after #{delay}...")
-        sleep(delay)
-        begin
-          hg.pull('canonical')
-        rescue Exception
-          delay = 30 + rand * 100
-          info("Will retry after #{delay}...")
-          sleep(delay)
-          hg.pull('canonical')
-        end
-      end
+      hg.pull('canonical') if repository.canonical
 
       # If revision is not specified, then look for an active bookmark
       # and update to it. If no bookmark is active, then look for bookmark
@@ -299,22 +285,7 @@
 
       hg.pull('origin') if repository.origin
       hg.pull('upstream') if repository.upstream
-
-      begin
-        hg.pull('canonical') if repository.canonical
-      rescue Exception
-        delay = 30 + rand * 100
-        info("Will retry after #{delay}...")
-        sleep(delay)
-        begin
-          hg.pull('canonical')
-        rescue Exception
-          delay = 30 + rand * 100
-          info("Will retry after #{delay}...")
-          sleep(delay)
-          hg.pull('canonical')
-        end
-      end
+      hg.pull('canonical') if repository.canonical
 
       # If revision is not specified, then look for bookmark
       # `master`. If it exist, then check out `master`. If it