<commit_before>/*
 *  Copyright (c) 2016, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */
#include "FileObserver.h"

#include <memory>
#include <vector>

#include <glog/logging.h>

#include <folly/io/async/EventBase.h>
#include <folly/Memory.h>

#include "mcrouter/FileDataProvider.h"
#include "mcrouter/McrouterLogFailure.h"

namespace facebook { namespace memcache { namespace mcrouter {

namespace {

void checkAndExecuteFallbackOnError(std::function<void()> fallbackOnError) {
  if (fallbackOnError) {
    LOG(INFO) << "Calling the fallbackOnError function";
    fallbackOnError();
  }
}

struct FileObserverData {
  FileObserverData(std::shared_ptr<FileDataProvider> provider__,
                   std::function<void(std::string)> onUpdate__,
                   std::function<void()> fallbackOnError__,
                   uint32_t pollPeriodMs__,
                   uint32_t sleepBeforeUpdateMs__)
      : provider(std::move(provider__)),
        onUpdate(std::move(onUpdate__)),
        fallbackOnError(std::move(fallbackOnError__)),
        pollPeriodMs(pollPeriodMs__),
        sleepBeforeUpdateMs(sleepBeforeUpdateMs__) {}
  std::shared_ptr<FileDataProvider> provider;
  std::function<void(std::string)> onUpdate;
  std::function<void()> fallbackOnError;
  uint32_t pollPeriodMs;
  uint32_t sleepBeforeUpdateMs;
};

void scheduleObserveFile(folly::EventBase& evb, FileObserverData data) {
  evb.runAfterDelay([&evb, data = std::move(data)]() {
    bool hasUpdate;
    try {
      hasUpdate = data.provider->hasUpdate();
    } catch (...) {
      checkAndExecuteFallbackOnError(std::move(data.fallbackOnError));
      LOG_FAILURE("mcrouter", failure::Category::kOther,
                  "Error while observing file for update");
      return;
    }

    if (hasUpdate) {
      evb.runAfterDelay([&evb, data = std::move(data)]() {
        try {
          data.onUpdate(data.provider->load());
          scheduleObserveFile(evb, std::move(data));
        } catch (...) {
          checkAndExecuteFallbackOnError(std::move(data.fallbackOnError));
          LOG_FAILURE("mcrouter", failure::Category::kOther,
                      "Error while observing file for update");
        }
      }, data.sleepBeforeUpdateMs);
    } else {
      scheduleObserveFile(evb, std::move(data));
    }
  }, data.pollPeriodMs);
}

} // anonymous namespace

bool startObservingFile(const std::string& filePath,
                        folly::EventBase& evb,
                        uint32_t pollPeriodMs,
                        uint32_t sleepBeforeUpdateMs,
                        std::function<void(std::string)> onUpdate,
                        std::function<void()> fallbackOnError) {

  std::shared_ptr<FileDataProvider> provider;
  try {
    provider = std::make_shared<FileDataProvider>(filePath);

    onUpdate(provider->load());
  } catch (const std::exception& e) {<commit_msg>Use after move in mcrouter project<commit_after>/*
 *  Copyright (c) 2016, Facebook, Inc.
 *  All rights reserved.
 *
 *  This source code is licensed under the BSD-style license found in the
 *  LICENSE file in the root directory of this source tree. An additional grant
 *  of patent rights can be found in the PATENTS file in the same directory.
 *
 */
#include "FileObserver.h"

#include <memory>
#include <vector>

#include <glog/logging.h>

#include <folly/io/async/EventBase.h>
#include <folly/Memory.h>

#include "mcrouter/FileDataProvider.h"
#include "mcrouter/McrouterLogFailure.h"

namespace facebook { namespace memcache { namespace mcrouter {

namespace {

void checkAndExecuteFallbackOnError(std::function<void()> fallbackOnError) {
  if (fallbackOnError) {
    LOG(INFO) << "Calling the fallbackOnError function";
    fallbackOnError();
  }
}

struct FileObserverData {
  FileObserverData(std::shared_ptr<FileDataProvider> provider__,
                   std::function<void(std::string)> onUpdate__,
                   std::function<void()> fallbackOnError__,
                   uint32_t pollPeriodMs__,
                   uint32_t sleepBeforeUpdateMs__)
      : provider(std::move(provider__)),
        onUpdate(std::move(onUpdate__)),
        fallbackOnError(std::move(fallbackOnError__)),
        pollPeriodMs(pollPeriodMs__),
        sleepBeforeUpdateMs(sleepBeforeUpdateMs__) {}
  std::shared_ptr<FileDataProvider> provider;
  std::function<void(std::string)> onUpdate;
  std::function<void()> fallbackOnError;
  uint32_t pollPeriodMs;
  uint32_t sleepBeforeUpdateMs;
};

void scheduleObserveFile(folly::EventBase& evb, FileObserverData data) {
  uint32_t pollPeriodMs = data.pollPeriodMs;
  evb.runAfterDelay([&evb, data = std::move(data)]() {
    bool hasUpdate;
    try {
      hasUpdate = data.provider->hasUpdate();
    } catch (...) {
      checkAndExecuteFallbackOnError(std::move(data.fallbackOnError));
      LOG_FAILURE("mcrouter", failure::Category::kOther,
                  "Error while observing file for update");
      return;
    }

    if (hasUpdate) {
      uint32_t sleepBeforeUpdateMs = data.sleepBeforeUpdateMs;
      evb.runAfterDelay([&evb, data = std::move(data)]() {
        auto fallbackOnError = data.fallbackOnError;
        try {
          data.onUpdate(data.provider->load());
          scheduleObserveFile(evb, std::move(data));
        } catch (...) {
          checkAndExecuteFallbackOnError(std::move(fallbackOnError));
          LOG_FAILURE("mcrouter", failure::Category::kOther,
                      "Error while observing file for update");
        }
      }, sleepBeforeUpdateMs);
    } else {
      scheduleObserveFile(evb, std::move(data));
    }
  }, pollPeriodMs);
}

} // anonymous namespace

bool startObservingFile(const std::string& filePath,
                        folly::EventBase& evb,
                        uint32_t pollPeriodMs,
                        uint32_t sleepBeforeUpdateMs,
                        std::function<void(std::string)> onUpdate,
                        std::function<void()> fallbackOnError) {

  std::shared_ptr<FileDataProvider> provider;
  try {
    provider = std::make_shared<FileDataProvider>(filePath);

    onUpdate(provider->load());
  } catch (const std::exception& e) {
{'fraction_non_alphanumeric': 0.11746280344557557, 'fraction_numerical': 0.005638214565387627, 'mean_word_length': 3.162972620599739, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 41, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1520188', 'n_tokens_mistral': 1915, 'n_tokens_neox': 1868, 'n_words': 380}