(
self, graph: Graph
)
| 1493 | return [next_scc], bool(self.scc_queue), {} |
| 1494 | |
| 1495 | def wait_for_done_workers( |
| 1496 | self, graph: Graph |
| 1497 | ) -> tuple[list[SCC], bool, dict[str, ModuleResult]]: |
| 1498 | if not self.scc_queue and len(self.free_workers) == len(self.workers): |
| 1499 | return [], False, {} |
| 1500 | |
| 1501 | done_sccs = [] |
| 1502 | results = {} |
| 1503 | t0 = time.time() |
| 1504 | ready = ready_to_read([w.conn for w in self.workers], WORKER_DONE_TIMEOUT) |
| 1505 | t1 = time.time() |
| 1506 | for idx in ready: |
| 1507 | buf = self.receive_worker_message(idx) |
| 1508 | assert read_tag(buf) == SCC_RESPONSE_MESSAGE |
| 1509 | data = SccResponseMessage.read(buf) |
| 1510 | if not data.is_interface: |
| 1511 | # Mark worker as free after it finished checking implementation. |
| 1512 | self.free_workers.add(idx) |
| 1513 | if data.blocker is not None: |
| 1514 | raise data.blocker |
| 1515 | assert data.result is not None |
| 1516 | results.update(data.result) |
| 1517 | if data.is_interface: |
| 1518 | done_sccs.extend([self.scc_by_id[scc_id] for scc_id in data.scc_ids]) |
| 1519 | self.add_stats(scc_wait_time=t1 - t0, scc_receive_time=time.time() - t1) |
| 1520 | self.submit_to_workers(graph) # advance after some workers are free. |
| 1521 | return ( |
| 1522 | # Note that "done" means interface-ready in this context. This is what |
| 1523 | # the caller should expect. |
| 1524 | done_sccs, |
| 1525 | bool(self.scc_queue) or len(self.free_workers) < len(self.workers), |
| 1526 | results, |
| 1527 | ) |
| 1528 | |
| 1529 | def is_transitive_scc_dep(self, from_scc_id: int, to_scc_id: int) -> bool: |
| 1530 | """Check if one SCC is a (transitive) dependency of another.""" |
no test coverage detected