folly/folly/io/async/Request.h

/*
 * Copyright (c) Meta Platforms, Inc. and affiliates.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#pragma once

#include <atomic>
#include <memory>
#include <string>
#include <type_traits>
#include <utility>

#include <folly/SharedMutex.h>
#include <folly/SingletonThreadLocal.h>
#include <folly/Synchronized.h>
#include <folly/concurrency/ProcessLocalUniqueId.h>
#include <folly/container/F14Map.h>
#include <folly/detail/Iterators.h>
#include <folly/synchronization/Hazptr.h>

namespace folly {

/*
 * A token to be used to fetch data from RequestContext.
 * Generally you will want this to be a static, created only once using a
 * string, and then only copied. The string constructor is expensive.
 */
class RequestToken {};
static_assert;

} // namespace folly

namespace std {
template <>
struct hash<folly::RequestToken> {};
} // namespace std

namespace folly {

// Some request context that follows an async request through a process
// Everything in the context must be thread safe

class RequestData {};

/**
 * ImmutableRequestData is a folly::RequestData that holds an immutable value.
 * It is thread-safe (a requirement of RequestData) because it is immutable.
 */
template <typename T>
class ImmutableRequestData : public folly::RequestData {};

RequestDataItem;

class RequestContext {};
static_assert;

/**
 * RequestContextSaverScopeGuard allows to replace the current context
 * without switching back to original context, while ensuring that the original
 * context is restored on guard destruction.
 *
 * The constructor saves the current context but does not replace it; instead,
 * RequestContext::setContext() should be called directly. The original context
 * will be restored on guard destruction. This is different from
 * RequestContextScopeGuard which replaces the current context in construction.
 *
 * This enables taking advantage of the optimization in setContext() which skips
 * invoking the RequestData callbacks if the new context is the the same as the
 * current one. The use case is processing tasks in a loop which are likely to
 * share the same context.
 */
class RequestContextSaverScopeGuard {};

/**
 * Note: you probably want to use ShallowCopyRequestContextScopeGuard
 * This resets all other RequestData for the duration of the scope!
 */
class RequestContextScopeGuard : private RequestContextSaverScopeGuard {};

/**
 * This guard maintains all the RequestData pointers of the parent.
 * This allows to overwrite a specific RequestData pointer for the
 * scope's duration, without breaking others.
 *
 * Only modified pointers will have their set/onset methods called
 */
struct ShallowCopyRequestContextScopeGuard {};

template <class Traits>
/* static */ FOLLY_EXPORT RequestData*
RequestContext::getThreadCachedContextData() {}

} // namespace folly