(
&mut self,
dataflow: DataflowDescription<mz_compute_types::plan::Plan, ()>,
import_read_holds: Vec<ReadHold>,
mut shared_collection_state: BTreeMap<GlobalId, SharedCo
| 1393 | /// for each imported collection a read hold in `import_read_holds` at at least the `as_of`. |
| 1394 | #[mz_ore::instrument(level = "debug")] |
| 1395 | pub fn create_dataflow( |
| 1396 | &mut self, |
| 1397 | dataflow: DataflowDescription<mz_compute_types::plan::Plan, ()>, |
| 1398 | import_read_holds: Vec<ReadHold>, |
| 1399 | mut shared_collection_state: BTreeMap<GlobalId, SharedCollectionState>, |
| 1400 | target_replica: Option<ReplicaId>, |
| 1401 | ) -> Result<(), DataflowCreationError> { |
| 1402 | use DataflowCreationError::*; |
| 1403 | |
| 1404 | // Validate that the target replica, if specified, exists. |
| 1405 | // A targeted dataflow is only installed on a single replica; if that |
| 1406 | // replica doesn't exist, we can't create the dataflow. |
| 1407 | if let Some(replica_id) = target_replica { |
| 1408 | if !self.replica_exists(replica_id) { |
| 1409 | return Err(ReplicaMissing(replica_id)); |
| 1410 | } |
| 1411 | } |
| 1412 | |
| 1413 | // Simple sanity checks around `as_of` |
| 1414 | let as_of = dataflow.as_of.as_ref().ok_or(MissingAsOf)?; |
| 1415 | if as_of.is_empty() && dataflow.subscribe_ids().next().is_some() { |
| 1416 | return Err(EmptyAsOfForSubscribe); |
| 1417 | } |
| 1418 | if as_of.is_empty() && dataflow.copy_to_ids().next().is_some() { |
| 1419 | return Err(EmptyAsOfForCopyTo); |
| 1420 | } |
| 1421 | |
| 1422 | // Collect all dependencies of the dataflow, and read holds on them at the `as_of`. |
| 1423 | let mut storage_dependencies = BTreeMap::new(); |
| 1424 | let mut compute_dependencies = BTreeMap::new(); |
| 1425 | |
| 1426 | // When we install per-replica input read holds, we cannot use the `as_of` because of |
| 1427 | // reconciliation: Existing slow replicas might be reading from the inputs at times before |
| 1428 | // the `as_of` and we would rather not crash them by allowing their inputs to compact too |
| 1429 | // far. So instead we take read holds at the least time available. |
| 1430 | let mut replica_input_read_holds = Vec::new(); |
| 1431 | |
| 1432 | let mut import_read_holds: BTreeMap<_, _> = |
| 1433 | import_read_holds.into_iter().map(|r| (r.id(), r)).collect(); |
| 1434 | |
| 1435 | for &id in dataflow.source_imports.keys() { |
| 1436 | let mut read_hold = import_read_holds.remove(&id).ok_or(ReadHoldMissing(id))?; |
| 1437 | replica_input_read_holds.push(read_hold.clone()); |
| 1438 | |
| 1439 | read_hold |
| 1440 | .try_downgrade(as_of.clone()) |
| 1441 | .map_err(|_| ReadHoldInsufficient(id))?; |
| 1442 | storage_dependencies.insert(id, read_hold); |
| 1443 | } |
| 1444 | |
| 1445 | for &id in dataflow.index_imports.keys() { |
| 1446 | let mut read_hold = import_read_holds.remove(&id).ok_or(ReadHoldMissing(id))?; |
| 1447 | read_hold |
| 1448 | .try_downgrade(as_of.clone()) |
| 1449 | .map_err(|_| ReadHoldInsufficient(id))?; |
| 1450 | compute_dependencies.insert(id, read_hold); |
| 1451 | } |
| 1452 |
nothing calls this directly
no test coverage detected