MCPcopy Create free account
hub / github.com/MaterializeInc/materialize / build

Method build

src/timely-util/src/builder_async.rs:571–647  ·  view source on GitHub ↗

Creates an operator implementation from supplied logic constructor. It returns a shutdown button that when pressed it will cause the logic future to be dropped and input handles to be drained. The button can be converted into a token by using [`Button::press_on_drop`]

(self, constructor: B)

Source from the content-addressed store, hash-verified

569 /// be drained. The button can be converted into a token by using
570 /// [`Button::press_on_drop`]
571 pub fn build<B, L>(self, constructor: B) -> Button
572 where
573 B: FnOnce(Vec<Capability<T>>) -> L,
574 L: Future + 'static,
575 {
576 let operator_waker = self.operator_waker;
577 let mut input_frontiers = self.input_frontiers;
578 let mut input_queues = self.input_queues;
579 let mut output_flushes = self.output_flushes;
580 let mut shutdown_handle = self.shutdown_handle;
581 self.builder.build_reschedule(move |caps| {
582 let mut logic_fut = Some(Box::pin(constructor(caps)));
583 move |new_frontiers| {
584 operator_waker.active.store(true, Ordering::SeqCst);
585 for (i, queue) in input_queues.iter_mut().enumerate() {
586 // First, discover if there are any frontier notifications
587 let cur = &mut input_frontiers[i];
588 let new = new_frontiers[i].frontier();
589 if PartialOrder::less_than(&cur.borrow(), &new) {
590 queue.notify_progress(new.to_owned());
591 *cur = new.to_owned();
592 }
593 // Then accept all input into local queues. This step registers the received
594 // messages with progress tracking.
595 queue.accept_input();
596 }
597 operator_waker.active.store(false, Ordering::SeqCst);
598
599 // If our worker pressed the button we stop scheduling the logic future and/or
600 // draining the input handles to stop producing data and frontier updates
601 // downstream.
602 if shutdown_handle.local_pressed() {
603 // When all workers press their buttons we drop the logic future and start
604 // draining the input handles.
605 if shutdown_handle.all_pressed() {
606 logic_fut = None;
607 for queue in input_queues.iter_mut() {
608 queue.drain_input();
609 }
610 false
611 } else {
612 true
613 }
614 } else {
615 // Schedule the logic future if any of the wakers above marked the task as ready
616 if let Some(fut) = logic_fut.as_mut() {
617 if operator_waker.task_ready.load(Ordering::SeqCst) {
618 let waker = futures_util::task::waker_ref(&operator_waker);
619 let mut cx = Context::from_waker(&waker);
620 operator_waker.task_ready.store(false, Ordering::SeqCst);
621 if Pin::new(fut).poll(&mut cx).is_ready() {
622 // We're done with logic so deallocate the task
623 logic_fut = None;
624 }
625 // Flush all the outputs before exiting
626 for flush in output_flushes.iter_mut() {
627 (flush)();
628 }

Callers 15

make_tlsFunction · 0.45
unary_fallibleMethod · 0.45
concatenate_flattenMethod · 0.45
mz_replayMethod · 0.45
sourceFunction · 0.45
build_fallibleMethod · 0.45
async_operatorFunction · 0.45
gh_18837Function · 0.45
reclockFunction · 0.45
create_stateFunction · 0.45
run_create_schemaFunction · 0.45
run_upload_parquet_typesFunction · 0.45

Calls 15

storeMethod · 0.80
enumerateMethod · 0.80
notify_progressMethod · 0.80
accept_inputMethod · 0.80
local_pressedMethod · 0.80
all_pressedMethod · 0.80
drain_inputMethod · 0.80
is_someMethod · 0.80
frontierMethod · 0.45
borrowMethod · 0.45
to_ownedMethod · 0.45
as_mutMethod · 0.45

Tested by 1

mainFunction · 0.36