Example #1
0
void ProxyThread::proxyThreadRun() {
  FBI_ASSERT(proxy->router != nullptr);
  mcrouter_set_thread_name(pthread_self(), proxy->router->opts, "mcrpxy");

  while(!proxy->router->shutdownStarted()) {
    mcrouterLoopOnce(proxy->eventBase);
  }

  while (proxy->fiberManager.hasTasks()) {
    mcrouterLoopOnce(proxy->eventBase);
  }

  proxy->stopAwriterThreads();
  // Delete the proxy from the proxy thread so that the clients get
  // deleted from the same thread where they were created.
  folly::EventBase *eventBase = proxy->eventBase;
  std::unique_lock<std::mutex> lk(mux);
  // This is to avoid a race condition where proxy is deleted
  // before the call to stopAndJoin is made.
  cv.wait(lk,
    [this]() {
      return this->isSafeToDeleteProxy;
    });
  delete proxy;
  if (eventBase != nullptr) {
    delete eventBase;
  }
}
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.
  }
}