pub(crate) fn spawn_node_execution(
    context_factory: &N::Context,
    node: &N,
    entry_id: EntryId,
    run_token: RunToken,
    generation: Generation,
    previous_dep_generations: Option<Vec<Generation>>,
    previous_result: Option<EntryResult<N>>,
  ) -> EntryState<N> {
    // Increment the RunToken to uniquely identify this work.
    let previous_run_token = run_token;
    let run_token = run_token.next();
    let context = context_factory.clone_for(entry_id, run_token);
    let node = node.clone();
    let (abort_handle, abort_registration) = AbortHandle::new_pair();
    trace!(
      "Running node {:?} with {:?}. It was: previous_result={:?}",
      node,
      run_token,
      previous_result,
    );

    context_factory.spawn(async move {
      // If we have previous result generations, compare them to all current dependency
      // generations (which, if they are dirty, will cause recursive cleaning). If they
      // match, we can consider the previous result value to be clean for reuse.
      let was_clean = if let Some(previous_dep_generations) = previous_dep_generations {
        trace!("Getting deps to attempt to clean {}", node);
        match context
          .graph()
          .dep_generations(entry_id, previous_run_token, &context)
          .await
        {
          Ok(ref dep_generations) if dep_generations == &previous_dep_generations => {
            trace!("Deps matched: {} is clean.", node);
            // Dependencies have not changed: Node is clean.
            true
          }
          _ => {
            // If dependency generations mismatched or failed to fetch, indicate that the Node
            // should re-run.
            trace!("Deps did not match: {} needs to re-run.", node);
            false
          }
        }
      } else {
        false
      };

      // If the Node was clean, complete it. Otherwise, re-run.
      if was_clean {
        // No dependencies have changed: we can complete the Node without changing its
        // previous_result or generation.
        context
          .graph()
          .complete(&context, entry_id, run_token, None);
      } else {
        // The Node needs to (re-)run! Wrap the potentially long running computation in an
        // Abortable.
        let res = match Abortable::new(node.run(context.clone()), abort_registration).await {
          Ok(r) => r,
          Err(Aborted) => Err(N::Error::invalidated()),
        };

        context
          .graph()
          .complete(&context, entry_id, run_token, Some(res));
      }
    });

    EntryState::Running {
      run_token,
      abort_handle,
      waiters: Vec::new(),
      generation,
      previous_result,
    }
  }
///
/// Spawn the execution of the node on an Executor, which will cause it to execute outside of
/// the Graph lock and call back into the graph lock to set the final value.
///
Spawn the execution of the node on an Executor, which will cause it to execute outside of
the Graph lock and call back into the graph lock to set the final value.
Spawn the execution of the node on an Executor which will cause it to execute outside of the Graph lock and call back into the graph lock to set the final value .
pub(crate) fn spawn_node_execution(
    context_factory: &N::Context,
    node: &N,
    entry_id: EntryId,
    run_token: RunToken,
    generation: Generation,
    previous_dep_generations: Option<Vec<Generation>>,
    previous_result: Option<EntryResult<N>>,
  ) -> EntryState<N> {
    // Increment the RunToken to uniquely identify this work.
    let previous_run_token = run_token;
    let run_token = run_token.next();
    let context = context_factory.clone_for(entry_id, run_token);
    let node = node.clone();
    let (abort_handle, abort_registration) = AbortHandle::new_pair();
    trace!(
      "Running node {:?} with {:?}. It was: previous_result={:?}",
      node,
      run_token,
      previous_result,
    );
    context_factory.spawn(async move {
      // If we have previous result generations, compare them to all current dependency
      // generations (which, if they are dirty, will cause recursive cleaning). If they
      // match, we can consider the previous result value to be clean for reuse.
      let was_clean = if let Some(previous_dep_generations) = previous_dep_generations {
        trace!("Getting deps to attempt to clean {}", node);
        match context
          .graph()
          .dep_generations(entry_id, previous_run_token, &context)
          .await
        {
          Ok(ref dep_generations) if dep_generations == &previous_dep_generations => {
            trace!("Deps matched: {} is clean.", node);
            // Dependencies have not changed: Node is clean.
            true
          }
          _ => {
            // If dependency generations mismatched or failed to fetch, indicate that the Node
            // should re-run.
            trace!("Deps did not match: {} needs to re-run.", node);
            false
          }
        }
      } else {
        false
      };
      // If the Node was clean, complete it. Otherwise, re-run.
      if was_clean {
        // No dependencies have changed: we can complete the Node without changing its
        // previous_result or generation.
        context
          .graph()
          .complete(&context, entry_id, run_token, None);
      } else {
        // The Node needs to (re-)run! Wrap the potentially long running computation in an
        // Abortable.
        let res = match Abortable::new(node.run(context.clone()), abort_registration).await {
          Ok(r) => r,
          Err(Aborted) => Err(N::Error::invalidated()),
        };
        context
          .graph()
          .complete(&context, entry_id, run_token, Some(res));
      }
    });
    EntryState::Running {
      run_token,
      abort_handle,
      waiters: Vec::new(),
      generation,
      previous_result,
    }
  }
pub ( crate ) fn spawn_node_execution ( context_factory : & N :: Context , node : & N , entry_id : EntryId , run_token : RunToken , generation : Generation , previous_dep_generations : Option < Vec < Generation > > , previous_result : Option < EntryResult < N > > , ) -> EntryState < N > { // Increment the RunToken to uniquely identify this work. let previous_run_token = run_token ; let run_token = run_token . next ( ) ; let context = context_factory . clone_for ( entry_id , run_token ) ; let node = node . clone ( ) ; let ( abort_handle , abort_registration ) = AbortHandle :: new_pair ( ) ; trace ! ( " " node run_token previous_result ) ; context_factory . spawn ( async move { // If we have previous result generations, compare them to all current dependency // generations (which, if they are dirty, will cause recursive cleaning). If they // match, we can consider the previous result value to be clean for reuse. let was_clean = if let Some ( previous_dep_generations ) = previous_dep_generations { trace ! ( " " node ) ; match context . graph ( ) . dep_generations ( entry_id , previous_run_token , & context ) . await { Ok ( ref dep_generations ) if dep_generations == & previous_dep_generations => { trace ! ( " " node ) ; // Dependencies have not changed: Node is clean. true } _ => { // If dependency generations mismatched or failed to fetch, indicate that the Node // should re-run. trace ! ( " " node ) ; false } } } else { false } ; // If the Node was clean, complete it. Otherwise, re-run. if was_clean { // No dependencies have changed: we can complete the Node without changing its // previous_result or generation. context . graph ( ) . complete ( & context , entry_id , run_token , None ) ; } else { // The Node needs to (re-)run! Wrap the potentially long running computation in an // Abortable. let res = match Abortable :: new ( node . run ( context . clone ( ) ) , abort_registration ) . await { Ok ( r ) => r , Err ( Aborted ) => Err ( N :: Error :: invalidated ( ) ) , } ; context . graph ( ) . complete ( & context , entry_id , run_token , Some ( res ) ) ; } } ) ; EntryState :: Running { run_token , abort_handle , waiters : Vec :: new ( ) , generation , previous_result , } }
Spawn the execution of the node on an Executor, which will cause it to execute outside of
the Graph lock and call back into the graph lock to set the final value.
Spawn the execution of the node on an Executor which will cause it to execute outside of the Graph lock and call back into the graph lock to set the final value .
context_factory
&N::Context
node
&N
entry_id
EntryId
run_token
RunToken
generation
Generation
previous_dep_generations
Option<Vec<Generation>>
previous_result
Option<EntryResult<N>>
context_factory
&N::Context
node
&N
entry_id
EntryId
run_token
RunToken
generation
Generation
previous_dep_generations
Option<Vec<Generation>>
previous_result
Option<EntryResult<N>>