Add a cell to the graph. Mutates the graph, acquiring `self.lock`. Requires that `cell_id` is not already in the graph.
(self, cell_id: CellId_t, cell: CellImpl)
| 90 | return edges.get_referring_cells(name, language, self.topology) |
| 91 | |
| 92 | def register_cell(self, cell_id: CellId_t, cell: CellImpl) -> None: |
| 93 | """Add a cell to the graph. |
| 94 | |
| 95 | Mutates the graph, acquiring `self.lock`. |
| 96 | |
| 97 | Requires that `cell_id` is not already in the graph. |
| 98 | """ |
| 99 | LOGGER.debug("Acquiring graph lock to register cell %s", cell_id) |
| 100 | with self.lock: |
| 101 | LOGGER.debug("Acquired graph lock.") |
| 102 | assert cell_id not in self.topology.cells |
| 103 | |
| 104 | # Add the cell to topology |
| 105 | self.topology.add_node(cell_id, cell) |
| 106 | |
| 107 | # Process definitions and build sibling relationships FIRST |
| 108 | # This must happen before computing edges because edge computation |
| 109 | # needs to look up definitions |
| 110 | for name, variable_data in cell.variable_data.items(): |
| 111 | self.definition_registry.register_definition( |
| 112 | cell_id, name, variable_data |
| 113 | ) |
| 114 | # Now compute edges (which can now find the definitions) |
| 115 | parents, children = edges.compute_edges_for_cell( |
| 116 | cell_id, cell, self.topology, self.definition_registry |
| 117 | ) |
| 118 | |
| 119 | # Add edges to topology |
| 120 | for parent_id in parents: |
| 121 | self.topology.add_edge(parent_id, cell_id) |
| 122 | # Detect cycle for this edge |
| 123 | self.cycle_tracker.detect_cycle_for_edge( |
| 124 | (parent_id, cell_id), self.topology |
| 125 | ) |
| 126 | |
| 127 | for child_id in children: |
| 128 | self.topology.add_edge(cell_id, child_id) |
| 129 | # Detect cycle for this edge |
| 130 | self.cycle_tracker.detect_cycle_for_edge( |
| 131 | (cell_id, child_id), self.topology |
| 132 | ) |
| 133 | |
| 134 | LOGGER.debug("Registered cell %s and released graph lock", cell_id) |
| 135 | if self.is_any_ancestor_stale(cell_id): |
| 136 | self.set_stale({cell_id}) |
| 137 | |
| 138 | if self.is_any_ancestor_disabled(cell_id): |
| 139 | cell.set_runtime_state(status="disabled-transitively") |
| 140 | |
| 141 | def is_any_ancestor_stale(self, cell_id: CellId_t) -> bool: |
| 142 | """Check if any ancestor of a cell is stale.""" |