예제 #1
0
파일: Receiver.cpp 프로젝트: 0x4139/wdt
std::unique_ptr<TransferReport> Receiver::finish() {
  std::unique_lock<std::mutex> instanceLock(instanceManagementMutex_);
  TransferStatus status = getTransferStatus();
  if (status == NOT_STARTED) {
    WLOG(WARNING) << "Even though transfer has not started, finish is called";
    // getTransferReport will set the error code to ERROR
    return getTransferReport();
  }
  if (status == THREADS_JOINED) {
    WLOG(WARNING) << "Threads have already been joined. Returning the "
                  << "transfer report";
    return getTransferReport();
  }
  if (!isJoinable_) {
    // TODO: don't complain about this when coming from runForever()
    WLOG(WARNING) << "The receiver is not joinable. The threads will never"
                  << " finish and this method will never return";
  }
  for (auto &receiverThread : receiverThreads_) {
    receiverThread->finish();
  }

  setTransferStatus(THREADS_JOINED);

  if (isJoinable_) {
    // Make sure to join the progress thread.
    progressTrackerThread_.join();
  }
  std::unique_ptr<TransferReport> report = getTransferReport();
  auto &summary = report->getSummary();
  bool transferSuccess = (report->getSummary().getErrorCode() == OK);
  fixAndCloseTransferLog(transferSuccess);
  auto totalSenderBytes = summary.getTotalSenderBytes();
  if (progressReporter_ && totalSenderBytes >= 0) {
    report->setTotalFileSize(totalSenderBytes);
    report->setTotalTime(durationSeconds(Clock::now() - startTime_));
    progressReporter_->end(report);
  }
  logPerfStats();

  WLOG(WARNING) << "WDT receiver's transfer has been finished";
  WLOG(INFO) << *report;
  return report;
}
예제 #2
0
파일: Sender.cpp 프로젝트: ffmpegd/wdt
void Sender::reportProgress() {
    WDT_CHECK(progressReportIntervalMillis_ > 0);
    int throughputUpdateIntervalMillis =
        options_.throughput_update_interval_millis;
    WDT_CHECK(throughputUpdateIntervalMillis >= 0);
    int throughputUpdateInterval =
        throughputUpdateIntervalMillis / progressReportIntervalMillis_;

    int64_t lastEffectiveBytes = 0;
    std::chrono::time_point<Clock> lastUpdateTime = Clock::now();
    int intervalsSinceLastUpdate = 0;
    double currentThroughput = 0;

    auto waitingTime = std::chrono::milliseconds(progressReportIntervalMillis_);
    LOG(INFO) << "Progress reporter tracking every "
              << progressReportIntervalMillis_ << " ms";
    while (true) {
        {
            std::unique_lock<std::mutex> lock(mutex_);
            conditionFinished_.wait_for(lock, waitingTime);
            if (transferStatus_ == THREADS_JOINED) {
                break;
            }
        }
        if (!dirQueue_->fileDiscoveryFinished()) {
            continue;
        }

        std::unique_ptr<TransferReport> transferReport = getTransferReport();
        intervalsSinceLastUpdate++;
        if (intervalsSinceLastUpdate >= throughputUpdateInterval) {
            auto curTime = Clock::now();
            int64_t curEffectiveBytes =
                transferReport->getSummary().getEffectiveDataBytes();
            double time = durationSeconds(curTime - lastUpdateTime);
            currentThroughput = (curEffectiveBytes - lastEffectiveBytes) / time;
            lastEffectiveBytes = curEffectiveBytes;
            lastUpdateTime = curTime;
            intervalsSinceLastUpdate = 0;
        }
        transferReport->setCurrentThroughput(currentThroughput);

        progressReporter_->progress(transferReport);
    }
}
예제 #3
0
파일: Sender.cpp 프로젝트: ffmpegd/wdt
std::unique_ptr<TransferReport> Sender::finish() {
    std::unique_lock<std::mutex> instanceLock(instanceManagementMutex_);
    VLOG(1) << "Sender::finish()";
    TransferStatus status = getTransferStatus();
    if (status == NOT_STARTED) {
        LOG(WARNING) << "Even though transfer has not started, finish is called";
        // getTransferReport will set the error code to ERROR
        return getTransferReport();
    }
    if (status == THREADS_JOINED) {
        VLOG(1) << "Threads have already been joined. Returning the"
                << " existing transfer report";
        return getTransferReport();
    }
    const bool twoPhases = options_.two_phases;
    bool progressReportEnabled =
        progressReporter_ && progressReportIntervalMillis_ > 0;
    for (auto &senderThread : senderThreads_) {
        senderThread->finish();
    }
    if (!twoPhases) {
        dirThread_.join();
    }
    WDT_CHECK(numActiveThreads_ == 0);
    setTransferStatus(THREADS_JOINED);
    if (progressReportEnabled) {
        progressReporterThread_.join();
    }
    std::vector<TransferStats> threadStats;
    for (auto &senderThread : senderThreads_) {
        threadStats.push_back(senderThread->moveStats());
    }

    bool allSourcesAcked = false;
    for (auto &senderThread : senderThreads_) {
        auto &stats = senderThread->getTransferStats();
        if (stats.getErrorCode() == OK) {
            // at least one thread finished correctly
            // that means all transferred sources are acked
            allSourcesAcked = true;
            break;
        }
    }

    std::vector<TransferStats> transferredSourceStats;
    for (auto port : transferRequest_.ports) {
        auto &transferHistory =
            transferHistoryController_->getTransferHistory(port);
        if (allSourcesAcked) {
            transferHistory.markAllAcknowledged();
        } else {
            transferHistory.returnUnackedSourcesToQueue();
        }
        if (options_.full_reporting) {
            std::vector<TransferStats> stats = transferHistory.popAckedSourceStats();
            transferredSourceStats.insert(transferredSourceStats.end(),
                                          std::make_move_iterator(stats.begin()),
                                          std::make_move_iterator(stats.end()));
        }
    }
    if (options_.full_reporting) {
        validateTransferStats(transferredSourceStats,
                              dirQueue_->getFailedSourceStats());
    }
    int64_t totalFileSize = dirQueue_->getTotalSize();
    double totalTime = durationSeconds(endTime_ - startTime_);
    std::unique_ptr<TransferReport> transferReport =
        folly::make_unique<TransferReport>(
            transferredSourceStats, dirQueue_->getFailedSourceStats(),
            threadStats, dirQueue_->getFailedDirectories(), totalTime,
            totalFileSize, dirQueue_->getCount());

    if (progressReportEnabled) {
        progressReporter_->end(transferReport);
    }
    if (options_.enable_perf_stat_collection) {
        PerfStatReport report(options_);
        for (auto &senderThread : senderThreads_) {
            report += senderThread->getPerfReport();
        }
        report += dirQueue_->getPerfReport();
        LOG(INFO) << report;
    }
    double directoryTime;
    directoryTime = dirQueue_->getDirectoryTime();
    LOG(INFO) << "Total sender time = " << totalTime << " seconds ("
              << directoryTime << " dirTime)"
              << ". Transfer summary : " << *transferReport
              << "\nTotal sender throughput = "
              << transferReport->getThroughputMBps() << " Mbytes/sec ("
              << transferReport->getSummary().getEffectiveTotalBytes() /
              (totalTime - directoryTime) / kMbToB
              << " Mbytes/sec pure transfer rate)";
    return transferReport;
}