Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Injectable singleton class #1974

Merged
merged 23 commits into from
Nov 20, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
8545b41
WIP
alyssawilk Oct 17, 2017
f5b6174
WIP
alyssawilk Oct 17, 2017
4c22f0c
Merge branch 'abseil' into singleton
alyssawilk Oct 17, 2017
7abd66c
WIP
alyssawilk Oct 18, 2017
83a8806
Merge branch 'refs/heads/master' into abseil
alyssawilk Oct 19, 2017
91f6bbb
Merge branch 'refs/heads/abseil' into singleton
alyssawilk Oct 19, 2017
1f57850
status
alyssawilk Oct 19, 2017
c21aa9b
fix format
alyssawilk Oct 19, 2017
f60506a
Merge branch 'refs/heads/master' into abseil
alyssawilk Oct 30, 2017
880829a
Merge branch 'abseil' into singleton
alyssawilk Oct 30, 2017
c568f7f
Merge branch 'master' into abseil
alyssawilk Oct 31, 2017
23295fd
Merge branch 'abseil' into singleton
alyssawilk Oct 31, 2017
afd1e6d
splitting out singleton classes, adding unit tests
alyssawilk Oct 31, 2017
5715662
abseil -> com_google_absl
alyssawilk Oct 31, 2017
7428aa2
Merge branch 'refs/heads/master' into abseil
alyssawilk Nov 2, 2017
b88692e
Merge branch 'refs/heads/abseil' into singleton
alyssawilk Nov 2, 2017
674c3e9
Moving singletons to source/common/singleton, adding detailed class c…
alyssawilk Nov 2, 2017
a156653
Merge branch 'refs/heads/master' into abseil
alyssawilk Nov 9, 2017
1a8af58
Merge branch 'abseil' into singleton
alyssawilk Nov 9, 2017
fea701e
bowing to the cult of pedagogy ("how many spaces after a period" -> h…
alyssawilk Nov 9, 2017
48d5b5f
Merge branch 'master' into abseil
alyssawilk Nov 20, 2017
e90ca87
Merge branch 'abseil' into singleton
alyssawilk Nov 20, 2017
cd31966
renaming abseil per declared workspace name (thanks jmillikin)
alyssawilk Nov 20, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions bazel/repositories.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,7 @@ def envoy_dependencies(path = "@envoy_deps//", skip_targets = []):
# The long repo names (`com_github_fmtlib_fmt` instead of `fmtlib`) are
# semi-standard in the Bazel community, intended to avoid both duplicate
# dependencies and name conflicts.
_com_google_absl()
_com_github_bombela_backward()
_com_github_cyan4973_xxhash()
_com_github_eile_tclap()
Expand Down Expand Up @@ -358,6 +359,13 @@ def _com_google_googletest():
actual = "@com_google_googletest//:gtest",
)

def _com_google_absl():
_repository_impl("com_google_absl")
native.bind(
name = "abseil_base",
actual = "@com_google_absl//absl/base:base",
)

def _com_google_protobuf():
_repository_impl("com_google_protobuf")

Expand Down
4 changes: 4 additions & 0 deletions bazel/repository_locations.bzl
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
REPOSITORY_LOCATIONS = dict(
com_google_absl = dict(
commit = "6de53819a7173bd446156237a37f53464b7732cc",
remote = "https://github.com/abseil/abseil-cpp",
),
com_github_bombela_backward = dict(
commit = "cd1c4bd9e48afe812a0e996d335298c455afcd92", # v1.3
remote = "https://github.com/bombela/backward-cpp",
Expand Down
1 change: 1 addition & 0 deletions source/common/api/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,6 @@ envoy_cc_library(
hdrs = ["os_sys_calls_impl.h"],
deps = [
"//include/envoy/api:os_sys_calls_interface",
"//source/common/singleton:threadsafe_singleton",
],
)
5 changes: 2 additions & 3 deletions source/common/api/api_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
#include <chrono>
#include <string>

#include "common/api/os_sys_calls_impl.h"
#include "common/event/dispatcher_impl.h"
#include "common/filesystem/filesystem_impl.h"

Expand All @@ -15,11 +14,11 @@ Event::DispatcherPtr Impl::allocateDispatcher() {
}

Impl::Impl(std::chrono::milliseconds file_flush_interval_msec)
: os_sys_calls_(new OsSysCallsImpl()), file_flush_interval_msec_(file_flush_interval_msec) {}
: file_flush_interval_msec_(file_flush_interval_msec) {}

Filesystem::FileSharedPtr Impl::createFile(const std::string& path, Event::Dispatcher& dispatcher,
Thread::BasicLockable& lock, Stats::Store& stats_store) {
return std::make_shared<Filesystem::FileImpl>(path, dispatcher, lock, *os_sys_calls_, stats_store,
return std::make_shared<Filesystem::FileImpl>(path, dispatcher, lock, stats_store,
file_flush_interval_msec_);
}

Expand Down
2 changes: 0 additions & 2 deletions source/common/api/api_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
#include <string>

#include "envoy/api/api.h"
#include "envoy/api/os_sys_calls.h"
#include "envoy/filesystem/filesystem.h"

namespace Envoy {
Expand All @@ -26,7 +25,6 @@ class Impl : public Api::Api {
std::string fileReadToEnd(const std::string& path) override;

private:
OsSysCallsPtr os_sys_calls_;
std::chrono::milliseconds file_flush_interval_msec_;
};

Expand Down
4 changes: 4 additions & 0 deletions source/common/api/os_sys_calls_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

#include "envoy/api/os_sys_calls.h"

#include "common/singleton/threadsafe_singleton.h"

namespace Envoy {
namespace Api {

Expand All @@ -19,5 +21,7 @@ class OsSysCallsImpl : public OsSysCalls {
int stat(const char* pathname, struct stat* buf) override;
};

typedef ThreadSafeSingleton<OsSysCallsImpl> OsSysCallsSingleton;

} // namespace Api
} // namespace Envoy
5 changes: 0 additions & 5 deletions source/common/common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,6 @@ envoy_cc_library(
hdrs = ["non_copyable.h"],
)

envoy_cc_library(
name = "singleton",
hdrs = ["singleton.h"],
)

envoy_cc_library(
name = "stl_helpers",
hdrs = ["stl_helpers.h"],
Expand Down
8 changes: 4 additions & 4 deletions source/common/config/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ envoy_cc_library(
hdrs = ["metadata.h"],
external_deps = ["envoy_base"],
deps = [
"//source/common/common:singleton",
"//source/common/protobuf",
"//source/common/singleton:const_singleton",
],
)

Expand All @@ -227,7 +227,7 @@ envoy_cc_library(
envoy_cc_library(
name = "resources_lib",
hdrs = ["resources.h"],
deps = ["//source/common/common:singleton"],
deps = ["//source/common/singleton:const_singleton"],
)

envoy_cc_library(
Expand Down Expand Up @@ -298,11 +298,11 @@ envoy_cc_library(
"//source/common/common:assert_lib",
"//source/common/common:hash_lib",
"//source/common/common:hex_lib",
"//source/common/common:singleton",
"//source/common/grpc:common_lib",
"//source/common/json:config_schemas_lib",
"//source/common/protobuf",
"//source/common/protobuf:utility_lib",
"//source/common/singleton:const_singleton",
"//source/common/stats:stats_lib",
],
)
Expand All @@ -311,5 +311,5 @@ envoy_cc_library(
name = "well_known_names",
srcs = ["well_known_names.cc"],
hdrs = ["well_known_names.h"],
deps = ["//source/common/common:singleton"],
deps = ["//source/common/singleton:const_singleton"],
)
2 changes: 1 addition & 1 deletion source/common/config/metadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

#include <string>

#include "common/common/singleton.h"
#include "common/protobuf/protobuf.h"
#include "common/singleton/const_singleton.h"

#include "api/base.pb.h"

Expand Down
2 changes: 1 addition & 1 deletion source/common/config/resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

#include <string>

#include "common/common/singleton.h"
#include "common/singleton/const_singleton.h"

namespace Envoy {
namespace Config {
Expand Down
2 changes: 1 addition & 1 deletion source/common/config/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@
#include "common/common/assert.h"
#include "common/common/hash.h"
#include "common/common/hex.h"
#include "common/common/singleton.h"
#include "common/grpc/common.h"
#include "common/protobuf/protobuf.h"
#include "common/protobuf/utility.h"
#include "common/singleton/const_singleton.h"

#include "api/base.pb.h"
#include "api/cds.pb.h"
Expand Down
2 changes: 1 addition & 1 deletion source/common/config/well_known_names.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

#include "envoy/common/exception.h"

#include "common/common/singleton.h"
#include "common/singleton/const_singleton.h"

#include "fmt/format.h"

Expand Down
1 change: 1 addition & 0 deletions source/common/filesystem/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ envoy_cc_library(
"//include/envoy/api:os_sys_calls_interface",
"//include/envoy/event:dispatcher_interface",
"//include/envoy/filesystem:filesystem_interface",
"//source/common/api:os_sys_calls_lib",
"//source/common/buffer:buffer_lib",
"//source/common/common:thread_lib",
],
Expand Down
7 changes: 4 additions & 3 deletions source/common/filesystem/filesystem_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include "envoy/event/timer.h"
#include "envoy/stats/stats.h"

#include "common/api/os_sys_calls_impl.h"
#include "common/common/assert.h"
#include "common/common/thread.h"

Expand Down Expand Up @@ -53,14 +54,14 @@ std::string fileReadToEnd(const std::string& path) {
}

FileImpl::FileImpl(const std::string& path, Event::Dispatcher& dispatcher,
Thread::BasicLockable& lock, Api::OsSysCalls& os_sys_calls,
Stats::Store& stats_store, std::chrono::milliseconds flush_interval_msec)
Thread::BasicLockable& lock, Stats::Store& stats_store,
std::chrono::milliseconds flush_interval_msec)
: path_(path), file_lock_(lock), flush_timer_(dispatcher.createTimer([this]() -> void {
stats_.flushed_by_timer_.inc();
flush_event_.notify_one();
flush_timer_->enableTimer(flush_interval_msec_);
})),
os_sys_calls_(os_sys_calls), flush_interval_msec_(flush_interval_msec),
os_sys_calls_(Api::OsSysCallsSingleton::get()), flush_interval_msec_(flush_interval_msec),
stats_{FILESYSTEM_STATS(POOL_COUNTER_PREFIX(stats_store, "filesystem."),
POOL_GAUGE_PREFIX(stats_store, "filesystem."))} {
open();
Expand Down
3 changes: 1 addition & 2 deletions source/common/filesystem/filesystem_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,7 @@ std::string fileReadToEnd(const std::string& path);
class FileImpl : public File {
public:
FileImpl(const std::string& path, Event::Dispatcher& dispatcher, Thread::BasicLockable& lock,
Api::OsSysCalls& osSysCalls, Stats::Store& stats_store,
std::chrono::milliseconds flush_interval_msec);
Stats::Store& stats_store, std::chrono::milliseconds flush_interval_msec);
~FileImpl();

// Filesystem::File
Expand Down
4 changes: 2 additions & 2 deletions source/common/http/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -166,8 +166,8 @@ envoy_cc_library(
"//source/common/common:assert_lib",
"//source/common/common:empty_string",
"//source/common/common:non_copyable",
"//source/common/common:singleton",
"//source/common/common:utility_lib",
"//source/common/singleton:const_singleton",
],
)

Expand All @@ -176,7 +176,7 @@ envoy_cc_library(
hdrs = ["headers.h"],
deps = [
"//include/envoy/http:header_map_interface",
"//source/common/common:singleton",
"//source/common/singleton:const_singleton",
],
)

Expand Down
2 changes: 1 addition & 1 deletion source/common/http/header_map_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

#include "common/common/assert.h"
#include "common/common/empty_string.h"
#include "common/common/singleton.h"
#include "common/common/utility.h"
#include "common/singleton/const_singleton.h"

namespace Envoy {
namespace Http {
Expand Down
2 changes: 1 addition & 1 deletion source/common/http/headers.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include "envoy/http/header_map.h"

#include "common/common/singleton.h"
#include "common/singleton/const_singleton.h"

namespace Envoy {
namespace Http {
Expand Down
2 changes: 1 addition & 1 deletion source/common/mongo/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@ envoy_cc_library(
"//source/common/buffer:buffer_lib",
"//source/common/common:assert_lib",
"//source/common/common:logger_lib",
"//source/common/common:singleton",
"//source/common/common:utility_lib",
"//source/common/config:filter_json_lib",
"//source/common/network:filter_lib",
"//source/common/protobuf:utility_lib",
"//source/common/singleton:const_singleton",
],
)

Expand Down
2 changes: 1 addition & 1 deletion source/common/mongo/proxy.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

#include "common/buffer/buffer_impl.h"
#include "common/common/logger.h"
#include "common/common/singleton.h"
#include "common/mongo/utility.h"
#include "common/network/filter_impl.h"
#include "common/protobuf/utility.h"
#include "common/singleton/const_singleton.h"

#include "api/filter/network/mongo_proxy.pb.h"

Expand Down
2 changes: 1 addition & 1 deletion source/common/ratelimit/ratelimit_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#include "envoy/tracing/http_tracer.h"
#include "envoy/upstream/cluster_manager.h"

#include "common/common/singleton.h"
#include "common/singleton/const_singleton.h"

#include "source/common/ratelimit/ratelimit.pb.h"

Expand Down
11 changes: 11 additions & 0 deletions source/common/singleton/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@ load(

envoy_package()

envoy_cc_library(
name = "const_singleton",
hdrs = ["const_singleton.h"],
)

envoy_cc_library(
name = "manager_impl_lib",
srcs = ["manager_impl.cc"],
Expand All @@ -19,3 +24,9 @@ envoy_cc_library(
"//source/common/common:thread_lib",
],
)

envoy_cc_library(
name = "threadsafe_singleton",
hdrs = ["threadsafe_singleton.h"],
external_deps = ["abseil_base"],
)
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@
namespace Envoy {

/**
* Immutable singleton pattern. See singleton/manager.h for mutable/destroyable singletons.
* ConstSingleton allows easy global cross-thread access to a const object.
*
* This singleton should be used for data which is initialized once at
* start-up and then be treated as immutable const data thereafter.
*/
template <class T> class ConstSingleton {
public:
Expand Down
44 changes: 44 additions & 0 deletions source/common/singleton/threadsafe_singleton.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#pragma once

#include "absl/base/call_once.h"

namespace Envoy {

/**
* ThreadSafeSingleton allows easy global cross-thread access to a non-const object.
*
* This singleton class should be used for singletons which must be globally
* accessible but can not be marked as const. All functions in the singleton class
* *must* be threadsafe.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It did occur to me that there is some truth-in-advertising issue with a ThreadSafeSingleton that isn't thread safe but forces you to be thread safe. Anyway, potatoes potatahs.

*
* Note that there is heavy resistence in Envoy to adding this type of singleton
* if data will persist with state changes across tests, as it becomes difficult
* to write clean unit tests if a state change in one test will persist into
* another test. Be wary of using it. A example of acceptable usage is OsSyscallsImpl,
* where the functions are not strictly speaking const, but affect the OS rather than the
* class itself. An example of unacceptable usage upstream would be for
* globally accessible stat counters, it would have the aforementioned problem
* where state "leaks" across tests.
*
* */
template <class T> class ThreadSafeSingleton {
public:
static T& get() {
absl::call_once(ThreadSafeSingleton<T>::create_once_, &ThreadSafeSingleton<T>::Create);
return *ThreadSafeSingleton<T>::instance_;
}

protected:
template <typename A> friend class TestThreadsafeSingletonInjector;

static void Create() { instance_ = new T(); }

static absl::once_flag create_once_;
static T* instance_;
};

template <class T> absl::once_flag ThreadSafeSingleton<T>::create_once_;

template <class T> T* ThreadSafeSingleton<T>::instance_ = nullptr;

} // namespace Envoy
2 changes: 1 addition & 1 deletion source/common/stats/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ envoy_cc_library(
"//include/envoy/server:options_interface",
"//include/envoy/stats:stats_interface",
"//source/common/common:assert_lib",
"//source/common/common:singleton",
"//source/common/common:utility_lib",
"//source/common/config:well_known_names",
"//source/common/protobuf",
"//source/common/singleton:const_singleton",
],
)

Expand Down
1 change: 0 additions & 1 deletion source/common/stats/stats_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
#include "envoy/stats/stats.h"

#include "common/common/assert.h"
#include "common/common/singleton.h"
#include "common/protobuf/protobuf.h"

#include "api/bootstrap.pb.h"
Expand Down
Loading