8041151: More concurrent hgforest

Fri, 11 Apr 2014 10:31:20 -0700

author
mduigou
date
Fri, 11 Apr 2014 10:31:20 -0700
changeset 1144
e16a393ee5e3
parent 1143
e3ae43560332
child 1145
3c596cad39e6

8041151: More concurrent hgforest
Reviewed-by: chegar, erikj, sla

common/bin/hgforest.sh file | annotate | diff | comparison | revisions
     1.1 --- a/common/bin/hgforest.sh	Fri Apr 11 09:35:03 2014 +0100
     1.2 +++ b/common/bin/hgforest.sh	Fri Apr 11 10:31:20 2014 -0700
     1.3 @@ -72,12 +72,21 @@
     1.4        exit 1
     1.5  }
     1.6  
     1.7 -
     1.8  if [ "x" = "x$command" ] ; then
     1.9    echo "ERROR: No command to hg supplied!"
    1.10    usage
    1.11  fi
    1.12  
    1.13 +# Check if we can use fifos for monitoring sub-process completion.
    1.14 +on_windows=`uname -s | egrep -ic -e 'cygwin|msys'`
    1.15 +if [ ${on_windows} = "1" ]; then
    1.16 +  # cygwin has (2014-04-18) broken (single writer only) FIFOs
    1.17 +  # msys has (2014-04-18) no FIFOs.
    1.18 +  have_fifos="false"
    1.19 +else
    1.20 +  have_fifos="true"
    1.21 +fi
    1.22 +
    1.23  # Clean out the temporary directory that stores the pid files.
    1.24  tmp=/tmp/forest.$$
    1.25  rm -f -r ${tmp}
    1.26 @@ -210,7 +219,19 @@
    1.27    ) &
    1.28  else
    1.29    # Run the supplied command on all repos in parallel.
    1.30 +
    1.31 +  # n is the number of subprocess started or which might still be running.
    1.32    n=0
    1.33 +  if [ $have_fifos = "true" ]; then
    1.34 +    # if we have fifos use them to detect command completion.
    1.35 +    mkfifo ${tmp}/fifo
    1.36 +    exec 3<>${tmp}/fifo
    1.37 +    if [ "${sflag}" = "true" ] ; then
    1.38 +      # force sequential
    1.39 +      at_a_time=1
    1.40 +    fi
    1.41 +  fi
    1.42 +
    1.43    for i in ${repos} ${repos_extra} ; do
    1.44      n=`expr ${n} '+' 1`
    1.45      repopidfile=`echo ${i} | sed -e 's@./@@' -e 's@/@_@g'`
    1.46 @@ -221,10 +242,11 @@
    1.47            pull_base="${pull_extra}"
    1.48        fi
    1.49      done
    1.50 +    pull_base="`echo ${pull_base} | sed -e 's@[/]*$@@'`"
    1.51      (
    1.52        (
    1.53          if [ "${command}" = "clone" -o "${command}" = "fclone" -o "${command}" = "tclone" ] ; then
    1.54 -          pull_newrepo="`echo ${pull_base}/${i} | sed -e 's@\([^:]/\)//*@\1@g'`"
    1.55 +          pull_newrepo="${pull_base}/${i}"
    1.56            path="`dirname ${i}`"
    1.57            if [ "${path}" != "." ] ; then
    1.58              times=0
    1.59 @@ -237,7 +259,7 @@
    1.60                sleep 5
    1.61              done
    1.62            fi
    1.63 -          echo "hg clone ${pull_newrepo} ${i}" > ${status_output}
    1.64 +          echo "hg${global_opts} clone ${pull_newrepo} ${i}" > ${status_output}
    1.65            (PYTHONUNBUFFERED=true hg${global_opts} clone ${pull_newrepo} ${i}; echo "$?" > ${tmp}/${repopidfile}.pid.rc ) 2>&1 &
    1.66          else
    1.67            echo "cd ${i} && hg${global_opts} ${command} ${command_args}" > ${status_output}
    1.68 @@ -246,21 +268,41 @@
    1.69  
    1.70          echo $! > ${tmp}/${repopidfile}.pid
    1.71        ) 2>&1 | sed -e "s@^@${reponame}:   @" > ${status_output}
    1.72 +      if [ $have_fifos = "true" ]; then
    1.73 +        echo "${reponame}" >&3
    1.74 +      fi
    1.75      ) &
    1.76  
    1.77 -    if [ `expr ${n} '%' ${at_a_time}` -eq 0 -a "${sflag}" = "false" ] ; then
    1.78 -      sleep 2
    1.79 -      echo "Waiting 5 secs before spawning next background command." > ${status_output}
    1.80 -      sleep 3
    1.81 -    fi
    1.82 -
    1.83 -    if [ "${sflag}" = "true" ] ; then
    1.84 +    if [ $have_fifos = "true" ]; then
    1.85 +      # check on count of running subprocesses and possibly wait for completion
    1.86 +      if [ ${at_a_time} -lt ${n} ] ; then
    1.87 +        # read will block until there are completed subprocesses
    1.88 +        while read repo_done; do
    1.89 +          n=`expr ${n} '-' 1`
    1.90 +          if [ ${n} -lt ${at_a_time} ] ; then
    1.91 +            # we should start more subprocesses
    1.92 +            break;
    1.93 +          fi
    1.94 +        done <&3
    1.95 +      fi
    1.96 +    else
    1.97 +      if [ "${sflag}" = "false" ] ; then
    1.98 +        # Compare completions to starts
    1.99 +        completed="`(ls -1 ${tmp}/*.pid.rc 2> /dev/null | wc -l) || echo 0`"
   1.100 +        while [ ${at_a_time} -lt `expr ${n} '-' ${completed}` ] ; do
   1.101 +          # sleep a short time to give time for something to complete
   1.102 +          sleep 1
   1.103 +          completed="`(ls -1 ${tmp}/*.pid.rc 2> /dev/null | wc -l) || echo 0`"
   1.104 +        done
   1.105 +      else
   1.106 +        # complete this task before starting another.
   1.107          wait
   1.108 +      fi
   1.109      fi
   1.110    done
   1.111  fi
   1.112  
   1.113 -# Wait for all hg commands to complete
   1.114 +# Wait for all subprocesses to complete
   1.115  wait
   1.116  
   1.117  # Terminate with exit 0 only if all subprocesses were successful
   1.118 @@ -270,7 +312,7 @@
   1.119      exit_code=`cat ${rc} | tr -d ' \n\r'`
   1.120      if [ "${exit_code}" != "0" ] ; then
   1.121        repo="`echo ${rc} | sed -e s@^${tmp}@@ -e 's@/*\([^/]*\)\.pid\.rc$@\1@' -e 's@_@/@g'`"
   1.122 -      echo "WARNING: ${repo} exited abnormally." > ${status_output}
   1.123 +      echo "WARNING: ${repo} exited abnormally ($exit_code)" > ${status_output}
   1.124        ec=1
   1.125      fi
   1.126    done

mercurial