void Foreman::run() { // Initialize before for Foreman eventloop. bool done = initialize(); // Event loop while (!done) { // Receive() causes this thread to sleep until next message is received. AnnotatedMessage annotated_msg = bus_->Receive(foreman_client_id_, 0, true); // Message is either workorder feedback message or foreman message. if (annotated_msg.tagged_message.message_type() == kWorkOrderFeedbackMessage) { WorkOrder::FeedbackMessage msg( const_cast<void *>(annotated_msg.tagged_message.message()), annotated_msg.tagged_message.message_bytes()); processFeedbackMessage(msg); } else { done = processMessage(*static_cast<const ForemanMessage *>( annotated_msg.tagged_message.message())); } } // Clean up before exiting. cleanUp(); }
QueryManager::QueryStatusCode QueryManager::processMessage( const TaggedMessage &tagged_message) { dag_node_index op_index; switch (tagged_message.message_type()) { case kWorkOrderCompleteMessage: { serialization::WorkOrderCompletionMessage proto; CHECK(proto.ParseFromArray(tagged_message.message(), tagged_message.message_bytes())); op_index = proto.operator_index(); processWorkOrderCompleteMessage(proto.operator_index()); break; } case kRebuildWorkOrderCompleteMessage: { serialization::WorkOrderCompletionMessage proto; CHECK(proto.ParseFromArray(tagged_message.message(), tagged_message.message_bytes())); op_index = proto.operator_index(); processRebuildWorkOrderCompleteMessage(proto.operator_index()); break; } case kCatalogRelationNewBlockMessage: { serialization::CatalogRelationNewBlockMessage proto; CHECK(proto.ParseFromArray(tagged_message.message(), tagged_message.message_bytes())); const block_id block = proto.block_id(); CatalogRelation *relation = static_cast<CatalogDatabase*>(catalog_database_)->getRelationByIdMutable(proto.relation_id()); relation->addBlock(block); if (proto.has_partition_id()) { relation->getPartitionSchemeMutable()->addBlockToPartition( proto.partition_id(), block); } return QueryStatusCode::kNone; } case kDataPipelineMessage: { // Possible message senders include InsertDestinations and some // operators which modify existing blocks. serialization::DataPipelineMessage proto; CHECK(proto.ParseFromArray(tagged_message.message(), tagged_message.message_bytes())); op_index = proto.operator_index(); processDataPipelineMessage(proto.operator_index(), proto.block_id(), proto.relation_id()); break; } case kWorkOrdersAvailableMessage: { serialization::WorkOrdersAvailableMessage proto; CHECK(proto.ParseFromArray(tagged_message.message(), tagged_message.message_bytes())); op_index = proto.operator_index(); // Check if new work orders are available. fetchNormalWorkOrders(op_index); // Dispatch the WorkerMessages to the workers. We prefer to start the search // for the schedulable WorkOrders beginning from 'op_index'. The first // candidate worker to receive the next WorkOrder is the one that sent the // response message to Foreman. // TODO(zuyu): Improve the data locality for the next WorkOrder. break; } case kWorkOrderFeedbackMessage: { WorkOrder::FeedbackMessage msg( const_cast<void *>(tagged_message.message()), tagged_message.message_bytes()); op_index = msg.header().rel_op_index; processFeedbackMessage(msg); break; } default: LOG(FATAL) << "Unknown message type found in QueryManager"; } if (query_exec_state_->hasExecutionFinished(op_index)) { return QueryStatusCode::kOperatorExecuted; } // As kQueryExecuted takes precedence over kOperatorExecuted, we check again. if (query_exec_state_->hasQueryExecutionFinished()) { return QueryStatusCode::kQueryExecuted; } return QueryStatusCode::kNone; }