Print 'Waiting for another process to install x, y, z' in distributed builds (#28535)
Co-authored-by: Massimiliano Culpo <massimiliano.culpo@gmail.com>
This commit is contained in:
		| @@ -648,6 +648,49 @@ def set(self, text): | ||||
|         sys.stdout.flush() | ||||
| 
 | ||||
| 
 | ||||
| class TermStatusLine(object): | ||||
|     """ | ||||
|     This class is used in distributed builds to inform the user that other packages are | ||||
|     being installed by another process. | ||||
|     """ | ||||
|     def __init__(self, enabled): | ||||
|         self.enabled = enabled | ||||
|         self.pkg_set = set() | ||||
|         self.pkg_list = [] | ||||
| 
 | ||||
|     def add(self, pkg_id): | ||||
|         """ | ||||
|         Add a package to the waiting list, and if it is new, update the status line. | ||||
|         """ | ||||
|         if not self.enabled or pkg_id in self.pkg_set: | ||||
|             return | ||||
| 
 | ||||
|         self.pkg_set.add(pkg_id) | ||||
|         self.pkg_list.append(pkg_id) | ||||
|         tty.msg(colorize('@*{Waiting for} @*g{%s}' % pkg_id)) | ||||
|         sys.stdout.flush() | ||||
| 
 | ||||
|     def clear(self): | ||||
|         """ | ||||
|         Clear the status line. | ||||
|         """ | ||||
|         if not self.enabled: | ||||
|             return | ||||
| 
 | ||||
|         lines = len(self.pkg_list) | ||||
| 
 | ||||
|         if lines == 0: | ||||
|             return | ||||
| 
 | ||||
|         self.pkg_set.clear() | ||||
|         self.pkg_list.clear() | ||||
| 
 | ||||
|         # Move the cursor to the beginning of the first "Waiting for" message and clear | ||||
|         # everything after it. | ||||
|         sys.stdout.write('\x1b[%sF\x1b[J' % lines) | ||||
|         sys.stdout.flush() | ||||
| 
 | ||||
| 
 | ||||
| class PackageInstaller(object): | ||||
|     ''' | ||||
|     Class for managing the install process for a Spack instance based on a | ||||
| @@ -1500,6 +1543,10 @@ def install(self): | ||||
| 
 | ||||
|         term_title = TermTitle(len(self.build_pq)) | ||||
| 
 | ||||
|         # Only enable the terminal status line when we're in a tty without debug info | ||||
|         # enabled, so that the output does not get cluttered. | ||||
|         term_status = TermStatusLine(enabled=sys.stdout.isatty() and not tty.is_debug()) | ||||
| 
 | ||||
|         while self.build_pq: | ||||
|             term_title.next_pkg() | ||||
| 
 | ||||
| @@ -1523,6 +1570,7 @@ def install(self): | ||||
|             # all subsequent tasks will have non-zero priorities or may be | ||||
|             # dependencies of this task. | ||||
|             if task.priority != 0: | ||||
|                 term_status.clear() | ||||
|                 tty.error('Detected uninstalled dependencies for {0}: {1}' | ||||
|                           .format(pkg_id, task.uninstalled_deps)) | ||||
|                 left = [dep_id for dep_id in task.uninstalled_deps if | ||||
| @@ -1545,12 +1593,14 @@ def install(self): | ||||
|             # some package likely depends on it. | ||||
|             if not task.explicit: | ||||
|                 if _handle_external_and_upstream(pkg, False): | ||||
|                     term_status.clear() | ||||
|                     self._flag_installed(pkg, task.dependents) | ||||
|                     continue | ||||
| 
 | ||||
|             # Flag a failed spec.  Do not need an (install) prefix lock since | ||||
|             # assume using a separate (failed) prefix lock file. | ||||
|             if pkg_id in self.failed or spack.store.db.prefix_failed(spec): | ||||
|                 term_status.clear() | ||||
|                 tty.warn('{0} failed to install'.format(pkg_id)) | ||||
|                 self._update_failed(task) | ||||
| 
 | ||||
| @@ -1569,6 +1619,7 @@ def install(self): | ||||
|             # determined the spec has already been installed (though the | ||||
|             # other process may be hung). | ||||
|             term_title.set('Acquiring lock for {0}'.format(pkg.name)) | ||||
|             term_status.add(pkg_id) | ||||
|             ltype, lock = self._ensure_locked('write', pkg) | ||||
|             if lock is None: | ||||
|                 # Attempt to get a read lock instead.  If this fails then | ||||
| @@ -1583,6 +1634,8 @@ def install(self): | ||||
|                 self._requeue_task(task) | ||||
|                 continue | ||||
| 
 | ||||
|             term_status.clear() | ||||
| 
 | ||||
|             # Take a timestamp with the overwrite argument to allow checking | ||||
|             # whether another process has already overridden the package. | ||||
|             if task.request.overwrite and task.explicit: | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Harmen Stoppels
					Harmen Stoppels