Exemple #1
0
void ConfigApi::configThreadRun() {
  mcrouterSetThreadName(pthread_self(), opts_, "mcrcfg");
  if (opts_.constantly_reload_configs) {
    while (!finish_) {
      LOG(INFO) << "Reload config due to constantly_reload_configs";
      callbacks_.notify();
      {
        std::unique_lock<std::mutex> lk(finishMutex_);
        finishCV_.wait_for(lk, std::chrono::milliseconds(10),
                           [this] { return finish_.load(); });

      }
    }
    return;
  }

  while (!finish_) {
    bool hasUpdate = false;
    try {
      hasUpdate = checkFileUpdate();
    } catch (const std::exception& e) {
      logFailure(memcache::failure::Category::kOther,
                 "Check for config update failed: {}", e.what());
    } catch (...) {
      logFailure(memcache::failure::Category::kOther,
                 "Check for config update failed with unknown error");
    }
    // There are a couple of races that can happen here
    // First, the IN_MODIFY event can be fired before the write is complete,
    // resulting in a malformed JSON error. Second, text editors may do
    // some of their own shuffling of the file (e.g. between .swp and the
    // real thing in Vim) after the write. This may can result in a file
    // access error router_configure_from_file below. That's just a theory,
    // but that error does happen. Race 1 can be fixed by changing the
    // watch for IN_MODIFY to IN_CLOSE_WRITE, but Race 2 has no apparent
    // elegant solution. The following jankiness fixes both.

    {
      std::unique_lock<std::mutex> lk(finishMutex_);
      finishCV_.wait_for(
        lk, std::chrono::milliseconds(opts_.reconfiguration_delay_ms),
        [this] { return finish_.load(); });

    }

    if (hasUpdate) {
      callbacks_.notify();
    }

    // Otherwise there was nothing to read, so check that we aren't shutting
    // down, and wait on the FD again.
  }
}
void ConfigApi::configThreadRun() {
  mcrouter_set_thread_name(pthread_self(), opts_, "mcrcfg");
  if (opts_.constantly_reload_configs) {
    while (!finish_) {
      LOG(INFO) << "Reload config due to constantly_reload_configs";
      callbacks_.notify();
      usleep(10000);
    }
    return;
  }

  while (!finish_) {
    bool hasUpdate;
    try {
      hasUpdate = checkFileUpdate();
    } catch (const std::exception& e) {
      LOG(ERROR) << "Check for config update failed: " << e.what();
      return;
    } catch (...) {
      LOG(ERROR) << "Check for config update failed with unknown error";
      return;
    }
    // There are a couple of races that can happen here
    // First, the IN_MODIFY event can be fired before the write is complete,
    // resulting in a malformed JSON error. Second, text editors may do
    // some of their own shuffling of the file (e.g. between .swp and the
    // real thing in Vim) after the write. This may can result in a file
    // access error router_configure_from_file below. That's just a theory,
    // but that error does happen. Race 1 can be fixed by changing the
    // watch for IN_MODIFY to IN_CLOSE_WRITE, but Race 2 has no apparent
    // elegant solution. The following jankiness fixes both.
    sleep(1);

    if (hasUpdate) {
      callbacks_.notify();
    }

    // Otherwise there was nothing to read, so check that we aren't shutting
    // down, and wait on the FD again.
  }
}