1# Initialize parallel lib
2-antigen-parallel-init () {
3  WARN "Init parallel extension" PARALLEL
4  typeset -ga _PARALLEL_BUNDLE; _PARALLEL_BUNDLE=()
5  if -antigen-interactive-mode; then
6    return 1
7  fi
8}
9
10-antigen-parallel-execute() {
11  WARN "Exec parallel extension" PARALLEL
12  # Install bundles in parallel
13  antigen-bundle-parallel-execute () {
14    WARN "Parallel antigen-bundle-parallel-execute" PARALLEL
15    typeset -a pids; pids=()
16    local args pid
17
18    WARN "Gonna install in parallel ${#_PARALLEL_BUNDLE} bundles." PARALLEL
19    # Do ensure-repo in parallel
20    WARN "${_PARALLEL_BUNDLE}" PARALLEL
21    typeset -Ua repositories # Used to keep track of cloned repositories to avoid
22                             # trying to clone it multiple times.
23    for args in ${_PARALLEL_BUNDLE}; do
24      typeset -A bundle; -antigen-parse-args 'bundle' ${=args}
25
26      if [[ ! -d ${bundle[dir]} && $repositories[(I)${bundle[url]}] == 0 ]]; then
27        WARN "Install in parallel ${bundle[name]}." PARALLEL
28        echo "Installing ${bundle[name]}!..."
29        # $bundle[url]'s format is "url|branch" as to create "$ANTIGEN_BUNDLES/bundle/name-branch",
30        # this way you may require multiple branches from the same repository.
31        -antigen-ensure-repo "${bundle[url]}" > /dev/null &!
32        pids+=($!)
33      else
34        WARN "Bundle ${bundle[name]} already cloned locally." PARALLEL
35      fi
36
37      repositories+=(${bundle[url]})
38    done
39
40    # Wait for all background processes to end
41    while [[ $#pids > 0 ]]; do
42      for pid in $pids; do
43        # `ps` may diplay an error message such "Signal 18 (CONT) caught by ps
44        # (procps-ng version 3.3.9).", see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=732410
45        if [[ $(ps -o pid= -p $pid 2>/dev/null) == "" ]]; then
46          pids[$pids[(I)$pid]]=()
47        fi
48      done
49      sleep .5
50    done
51
52    builtin local bundle &> /dev/null
53    for bundle in ${_PARALLEL_BUNDLE[@]}; do
54      antigen-bundle $bundle
55    done
56
57
58    WARN "Parallel install done" PARALLEL
59  }
60
61  # Hooks antigen-apply in order to release hooked functions
62  antigen-apply-parallel () {
63    WARN "Parallel pre-apply" PARALLEL PRE-APPLY
64    #antigen-remove-hook antigen-pre-apply-parallel
65    # Hooks antigen-bundle in order to parallel its execution.
66    antigen-bundle-parallel () {
67      TRACE "antigen-bundle-parallel: $@" PARALLEL
68      _PARALLEL_BUNDLE+=("${(j: :)${@}}")
69    }
70    antigen-add-hook antigen-bundle antigen-bundle-parallel replace
71  }
72  antigen-add-hook antigen-apply antigen-apply-parallel pre once
73
74  antigen-apply-parallel-execute () {
75      WARN "Parallel replace-apply" PARALLEL REPLACE-APPLY
76      antigen-remove-hook antigen-bundle-parallel
77      # Process all parallel bundles.
78      antigen-bundle-parallel-execute
79
80      unset _PARALLEL_BUNDLE
81      antigen-remove-hook antigen-apply-parallel-execute
82      antigen-apply
83  }
84  antigen-add-hook antigen-apply antigen-apply-parallel-execute replace once
85}
86