/** A thread that actually recevices data from remote worker. * @return If the action succeed, it will return 0. Otherwise, socket descriptor. */ void* TransferServer::transfer_server_thread(void) { static int32_t ret = 0; LOG_DEBUG("transfer_server_thread started - %u", pthread_self()); try { serverfd = CreateBindedSocket(start_port_range_, end_port_range_, &server_socket_port); } catch (...) { LOG_ERROR("transfer_server_thread - fail to open/bind a socket\n"); return reinterpret_cast<void*>(&ret); } LOG_DEBUG("transfer_server_thread socket bind complete. binded port: %u %d", pthread_self(), server_socket_port); int32_t new_fd = -1; struct sockaddr_in their_addr; socklen_t sin_size = sizeof(their_addr); ret = listen(serverfd, MAX_CONN); if (ret < 0) { fprintf(stderr, "listen failure\n"); sem_post(&server_ready); return reinterpret_cast<void*>(&ret); } sem_post(&server_ready); // TODO(shivaram): Check if it is okay if we only wait for one connection // Also this is blocking ! We need to use a select / libevent call // here new_fd = accept(serverfd, (struct sockaddr *) &their_addr, &sin_size); if (new_fd < 0) { ret = new_fd; return reinterpret_cast<void*>(&ret); } uint32_t sz; uint32_t size_bytes_read = 0; uint64_t recv_t = 0; #ifdef PROFILE_TRANSFER_TIME clock_gettime(CLOCK_REALTIME, &start_t); #endif bytes_fetched_ += (size_); atomicio(read, new_fd, dest_, size_); #ifdef PROFILE_TRANSFER_TIME clock_gettime(CLOCK_REALTIME, &end_t); recv_t = diff_clocktime(&start_t, &end_t); #endif close(new_fd); close(serverfd); ret = 0; return &ret; }
void PrestoMasterHandler::Run(context_t* ctx, int port_start, int port_end) { bool worker_abort_called = false; int port_num = -1; socket_t* sock; bool bind_succeed = true; try { sock = CreateBindedSocket(port_start, port_end, ctx, &port_num); } catch (...) { bind_succeed = false; } presto_master_->SetMasterPortNum(port_num); presto_master_->WorkerInfoSemaPost(); if (bind_succeed == false) { fprintf(stderr, "MasterHandler socket bind error. Check port number: %d\n", port_num); return; } MasterRequest master_req; try { while (true) { message_t request; boost::this_thread::interruption_point(); // check if interrupted sock->recv(&request); boost::this_thread::interruption_point(); // check if interrupted master_req.Clear(); master_req.ParseFromArray(request.data(), request.size()); switch (master_req.type()) { case MasterRequest::SHUTDOWN: LOG_INFO("PrestoMasterHanlder Shutdown is called"); delete sock; return; case MasterRequest::HELLOREPLY: { thread thr(boost::bind(&PrestoMaster::HandleHelloReply, presto_master_, master_req.helloreply())); } break; case MasterRequest::NEWUPDATE: { NewUpdateRequest nur = master_req.newupdate(); if (scheduler_->IsValidWorker(server_to_string(*nur.mutable_location())) == false) { break; } #ifdef MULTITHREADED_SCHEDULER thread thr(boost::bind(&PrestoMasterHandler::NewUpdate, this, master_req.newupdate())); #else NewUpdate(master_req.newupdate()); #endif } break; case MasterRequest::TASKDONE: { TaskDoneRequest tdr = master_req.taskdone(); if (scheduler_->IsValidWorker(server_to_string(*tdr.mutable_location())) == false) { break; } #ifdef MULTITHREADED_SCHEDULER thread thr(boost::bind( &PrestoMasterHandler::HandleTaskDone, this, master_req.taskdone())); #else bool ret = HandleTaskDone(master_req.taskdone()); // If an error happens during HandlingTaskDone message, shutdown the whole session if (ret == false) { LOG_ERROR("Error during processing task at worker (HandleTaskDone). Shutting down."); fprintf(stderr, "Error while processing task at worker." " We will shutdown the whole session. Use Ctrl-C to return to R console.\n"); thread thr(boost::bind(&PrestoMaster::Shutdown, presto_master_)); thr.detach(); return; } #endif } break; case MasterRequest::WORKERABORT: { WorkerAbortRequest war = master_req.workerabort(); if (scheduler_->IsValidWorker(server_to_string(*war.mutable_location())) == false) { break; } // if a shutdown message is already processed, // ignore further messages if (worker_abort_called == true) { break; } worker_abort_called = true; fprintf(stderr, "\n%sWorker aborted\n%s\n" "We will shutdown the whole session.\n", exception_prefix.c_str(), master_req.workerabort().reason().c_str()); ostringstream msg; msg << exception_prefix << "Worker aborted. "<< master_req.workerabort().reason().c_str() << "\nWe will shutdown the whole session"; LOG_INFO(msg.str()); thread thr(boost::bind(&PrestoMaster::Shutdown, presto_master_)); thr.detach(); } break; default: { LOG_ERROR("Unknown message received from Worker. Possible reasons - Check the correctness of the configuration - Either Hostname or Port of the Master and Workers has to be different"); fprintf(stderr, "Unknown message type received - Possible reasons\n" "Check the correctness of the configuration - Either Hostname or Port of the Master and Workers has to be different\n"); } } } }catch(boost::thread_interrupted const& ) { LOG_INFO("PrestoMasterHandler - interrupted."); delete sock; return; } catch (zmq::error_t err) { //LOG_INFO("PrestoMasterHandler - zmq error_t exception received. Teminate MasterHandler"); delete sock; return; } delete sock; }