예제 #1
0
Status FileLoader::do_loop() {
  TRY_RESULT(check_info,
             check_loop(parts_manager_.get_checked_prefix_size(), parts_manager_.get_unchecked_ready_prefix_size(),
                        parts_manager_.unchecked_ready()));
  if (check_info.changed) {
    on_progress_impl(narrow_cast<size_t>(parts_manager_.get_ready_size()));
  }
  for (auto &query : check_info.queries) {
    G()->net_query_dispatcher().dispatch_with_callback(
        std::move(query), actor_shared(this, UniqueId::next(UniqueId::Type::Default, CommonQueryKey)));
  }
  if (check_info.need_check) {
    parts_manager_.set_need_check();
    parts_manager_.set_checked_prefix_size(check_info.checked_prefix_size);
  }

  if (parts_manager_.ready()) {
    TRY_STATUS(parts_manager_.finish());
    TRY_STATUS(on_ok(parts_manager_.get_size()));
    LOG(INFO) << "Bad download order rate: "
              << (debug_total_parts_ == 0 ? 0.0 : 100.0 * debug_bad_part_order_ / debug_total_parts_) << "% "
              << debug_bad_part_order_ << "/" << debug_total_parts_ << " " << format::as_array(debug_bad_parts_);
    stop_flag_ = true;
    return Status::OK();
  }

  TRY_STATUS(before_start_parts());
  SCOPE_EXIT {
    after_start_parts();
  };
  while (true) {
    if (blocking_id_ != 0) {
      break;
    }
    if (resource_state_.unused() < static_cast<int64>(parts_manager_.get_part_size())) {
      VLOG(files) << "Got only " << resource_state_.unused() << " resource";
      break;
    }
    TRY_RESULT(part, parts_manager_.start_part());
    if (part.size == 0) {
      break;
    }
    VLOG(files) << "Start part " << tag("id", part.id) << tag("size", part.size);
    resource_state_.start_use(static_cast<int64>(part.size));

    TRY_RESULT(query_flag, start_part(part, parts_manager_.get_part_count()));
    NetQueryPtr query;
    bool is_blocking;
    std::tie(query, is_blocking) = std::move(query_flag);
    uint64 id = UniqueId::next();
    if (is_blocking) {
      CHECK(blocking_id_ == 0);
      blocking_id_ = id;
    }
    part_map_[id] = std::make_pair(part, query->cancel_slot_.get_signal_new());
    // part_map_[id] = std::make_pair(part, query.get_weak());

    auto callback = actor_shared(this, id);
    if (delay_dispatcher_.empty()) {
      G()->net_query_dispatcher().dispatch_with_callback(std::move(query), std::move(callback));
    } else {
      send_closure(delay_dispatcher_, &DelayDispatcher::send_with_callback_and_delay, std::move(query),
                   std::move(callback), next_delay_);
      next_delay_ = std::max(next_delay_ * 0.8, 0.003);
    }
  }
  return Status::OK();
}
예제 #2
0
void
MessageBox::on_ok_button()
{
  hide();
  on_ok();
}