@@ -48,12 +48,18 @@ namespace doris::pipeline {
4848
4949PipelineTask::PipelineTask (
5050 PipelinePtr& pipeline, uint32_t task_id, RuntimeState* state,
51- PipelineFragmentContext* fragment_context, RuntimeProfile* parent_profile,
51+ std::shared_ptr< PipelineFragmentContext> fragment_context, RuntimeProfile* parent_profile,
5252 std::map<int ,
5353 std::pair<std::shared_ptr<LocalExchangeSharedState>, std::shared_ptr<Dependency>>>
5454 le_state_map,
5555 int task_idx)
56- : _index(task_id),
56+ :
57+ #ifdef BE_TEST
58+ _query_id (fragment_context ? fragment_context->get_query_id () : TUniqueId()),
59+ #else
60+ _query_id (fragment_context->get_query_id ()),
61+ #endif
62+ _index (task_id),
5763 _pipeline(pipeline),
5864 _opened(false ),
5965 _state(state),
@@ -120,8 +126,10 @@ Status PipelineTask::prepare(const TPipelineInstanceParams& local_params, const
120126 std::unique_lock<std::mutex> lc (_dependency_lock);
121127 filter_dependencies.swap (_filter_dependencies);
122128 }
123- if (query_context ()->is_cancelled ()) {
124- clear_blocking_state ();
129+ if (auto fragment = _fragment_context.lock ()) {
130+ if (fragment->get_query_ctx ()->is_cancelled ()) {
131+ clear_blocking_state ();
132+ }
125133 }
126134 return Status::OK ();
127135}
@@ -225,14 +233,14 @@ bool PipelineTask::_wait_to_start() {
225233 // Before task starting, we should make sure
226234 // 1. Execution dependency is ready (which is controlled by FE 2-phase commit)
227235 // 2. Runtime filter dependencies are ready
228- _blocked_dep = _execution_dep->is_blocked_by (this );
236+ _blocked_dep = _execution_dep->is_blocked_by (shared_from_this () );
229237 if (_blocked_dep != nullptr ) {
230238 static_cast <Dependency*>(_blocked_dep)->start_watcher ();
231239 return true ;
232240 }
233241
234242 for (auto * op_dep : _filter_dependencies) {
235- _blocked_dep = op_dep->is_blocked_by (this );
243+ _blocked_dep = op_dep->is_blocked_by (shared_from_this () );
236244 if (_blocked_dep != nullptr ) {
237245 _blocked_dep->start_watcher ();
238246 return true ;
@@ -253,7 +261,7 @@ bool PipelineTask::_is_blocked() {
253261 for (int i = _read_dependencies.size () - 1 ; i >= 0 ; i--) {
254262 // `_read_dependencies` is organized according to operators. For each operator, running condition is met iff all dependencies are ready.
255263 for (auto * dep : _read_dependencies[i]) {
256- _blocked_dep = dep->is_blocked_by (this );
264+ _blocked_dep = dep->is_blocked_by (shared_from_this () );
257265 if (_blocked_dep != nullptr ) {
258266 _blocked_dep->start_watcher ();
259267 return true ;
@@ -272,7 +280,7 @@ bool PipelineTask::_is_blocked() {
272280 }
273281
274282 for (auto * op_dep : _write_dependencies) {
275- _blocked_dep = op_dep->is_blocked_by (this );
283+ _blocked_dep = op_dep->is_blocked_by (shared_from_this () );
276284 if (_blocked_dep != nullptr ) {
277285 _blocked_dep->start_watcher ();
278286 return true ;
@@ -282,6 +290,8 @@ bool PipelineTask::_is_blocked() {
282290}
283291
284292Status PipelineTask::execute (bool * eos) {
293+ auto fragment_context = _fragment_context.lock ();
294+ DCHECK (fragment_context);
285295 if (_eos) {
286296 *eos = true ;
287297 return Status::OK ();
@@ -318,7 +328,7 @@ Status PipelineTask::execute(bool* eos) {
318328 }
319329
320330 // The status must be runnable
321- if (!_opened && !_fragment_context ->is_canceled ()) {
331+ if (!_opened && !fragment_context ->is_canceled ()) {
322332 DBUG_EXECUTE_IF (" PipelineTask::execute.open_sleep" , {
323333 auto required_pipeline_id =
324334 DebugPoints::instance ()->get_debug_param_or_default <int32_t >(
@@ -350,7 +360,7 @@ Status PipelineTask::execute(bool* eos) {
350360
351361 _task_profile->add_info_string (" TaskState" , " Runnable" );
352362 _task_profile->add_info_string (" BlockedByDependency" , " " );
353- while (!_fragment_context ->is_canceled ()) {
363+ while (!fragment_context ->is_canceled ()) {
354364 SCOPED_RAW_TIMER (&time_spent);
355365 if (_is_blocked ()) {
356366 return Status::OK ();
@@ -359,7 +369,7 @@ Status PipelineTask::execute(bool* eos) {
359369 // / When a task is cancelled,
360370 // / its blocking state will be cleared and it will transition to a ready state (though it is not truly ready).
361371 // / Here, checking whether it is cancelled to prevent tasks in a blocking state from being re-executed.
362- if (_fragment_context ->is_canceled ()) {
372+ if (fragment_context ->is_canceled ()) {
363373 break ;
364374 }
365375
@@ -428,7 +438,7 @@ Status PipelineTask::execute(bool* eos) {
428438 }
429439 }
430440
431- RETURN_IF_ERROR (get_task_queue ()->push_back (this ));
441+ RETURN_IF_ERROR (get_task_queue ()->push_back (shared_from_this () ));
432442 return Status::OK ();
433443}
434444
@@ -490,6 +500,10 @@ bool PipelineTask::should_revoke_memory(RuntimeState* state, int64_t revocable_m
490500}
491501
492502void PipelineTask::finalize () {
503+ auto fragment = _fragment_context.lock ();
504+ if (!fragment) {
505+ return Status::OK ();
506+ }
493507 std::unique_lock<std::mutex> lc (_dependency_lock);
494508 _finalized = true ;
495509 _sink_shared_state.reset ();
@@ -532,28 +546,34 @@ std::string PipelineTask::debug_string() {
532546 std::unique_lock<std::mutex> lc (_dependency_lock);
533547 fmt::memory_buffer debug_string_buffer;
534548
535- fmt::format_to (debug_string_buffer, " QueryId: {}\n " , print_id (query_context ()-> query_id () ));
549+ fmt::format_to (debug_string_buffer, " QueryId: {}\n " , print_id (_query_id ));
536550 fmt::format_to (debug_string_buffer, " InstanceId: {}\n " ,
537551 print_id (_state->fragment_instance_id ()));
538552
553+ fmt::format_to (
554+ debug_string_buffer,
555+ " PipelineTask[this = {}, id = {}, open = {}, eos = {}, finalized = {}, dry run = "
556+ " {}, _wake_up_early = {}, is running = {}]" ,
557+ (void *)this , _index, _opened, _eos, _finalized, _dry_run, _wake_up_early.load (),
558+ is_running ());
559+ std::unique_lock<std::mutex> lc (_dependency_lock);
539560 auto * cur_blocked_dep = _blocked_dep;
540- auto elapsed = _fragment_context->elapsed_time () / 1000000000.0 ;
561+ auto fragment = _fragment_context.lock ();
562+ if (is_finalized () || !fragment) {
563+ return fmt::to_string (debug_string_buffer);
564+ }
565+ auto elapsed = fragment->elapsed_time () / NANOS_PER_SEC;
541566 fmt::format_to (debug_string_buffer,
542- " PipelineTask[this = {}, id = {}, open = {}, eos = {}, finish = {}, dry run = "
543- " {}, elapse time = {}s, _wake_up_early = {}], block dependency = {}, is "
544- " running = {}\n operators: " ,
545- (void *)this , _index, _opened, _eos, _finalized, _dry_run, elapsed,
546- _wake_up_early.load (),
547- cur_blocked_dep && !_finalized ? cur_blocked_dep->debug_string () : " NULL" ,
548- is_running ());
567+ " elapse time = {}s, block dependency = [{}]\n operators: " , elapsed,
568+ cur_blocked_dep && !is_finalized () ? cur_blocked_dep->debug_string () : " NULL" );
549569 for (size_t i = 0 ; i < _operators.size (); i++) {
550570 fmt::format_to (debug_string_buffer, " \n {}" ,
551571 _opened && !_finalized ? _operators[i]->debug_string (_state, i)
552572 : _operators[i]->debug_string (i));
553573 }
554574 fmt::format_to (debug_string_buffer, " \n {}\n " ,
555- _opened && !_finalized ? _sink->debug_string (_state, _operators.size ())
556- : _sink->debug_string (_operators.size ()));
575+ _opened && !is_finalized () ? _sink->debug_string (_state, _operators.size ())
576+ : _sink->debug_string (_operators.size ()));
557577 if (_finalized) {
558578 return fmt::to_string (debug_string_buffer);
559579 }
@@ -588,10 +608,7 @@ std::string PipelineTask::debug_string() {
588608
589609void PipelineTask::wake_up () {
590610 // call by dependency
591- static_cast <void >(get_task_queue ()->push_back (this ));
611+ static_cast <void >(get_task_queue ()->push_back (shared_from_this () ));
592612}
593613
594- QueryContext* PipelineTask::query_context () {
595- return _fragment_context->get_query_ctx ();
596- }
597614} // namespace doris::pipeline
0 commit comments