Skip to content
This repository has been archived by the owner on Dec 8, 2021. It is now read-only.

feat: configurable strategy for background threads #955

Merged
merged 4 commits into from
Oct 17, 2019
Merged

feat: configurable strategy for background threads #955

merged 4 commits into from
Oct 17, 2019

Conversation

coryan
Copy link
Contributor

@coryan coryan commented Oct 14, 2019

This change introduces an interface to represent the background
thread(s) used by a connection. I included two implementations in this
PR, one that automatically creates a single background thread, and
another that uses one or more threads provided by the application.

The ConnectionOptions class provides a factory for BackgroundThreads,
for those (we expect few) applications that will want to control the
background threads.

This fixes #606


This change is Reviewable

@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Oct 14, 2019
@codecov
Copy link

codecov bot commented Oct 14, 2019

Codecov Report

Merging #955 into master will increase coverage by 0.28%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #955      +/-   ##
==========================================
+ Coverage   94.27%   94.56%   +0.28%     
==========================================
  Files          92       94       +2     
  Lines        3932     3953      +21     
==========================================
+ Hits         3707     3738      +31     
+ Misses        225      215      -10
Impacted Files Coverage Δ
google/cloud/spanner/connection_options.cc 97.05% <100%> (+0.76%) ⬆️
...e/cloud/spanner/internal/background_threads_impl.h 100% <100%> (ø)
google/cloud/spanner/background_threads.h 100% <100%> (ø)
.../cloud/spanner/internal/background_threads_impl.cc 100% <100%> (ø)
google/cloud/spanner/connection_options.h 100% <100%> (ø) ⬆️
...loud/spanner/internal/partial_result_set_source.cc 93.93% <0%> (-1.45%) ⬇️
google/cloud/spanner/database_admin_connection.h
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c8cd120...294cfce. Read the comment docs.

This change introduces an interface to represent the background
thread(s) used by a connection. I included two implementations in this
PR, one that automatically creates a single background thread, and
another that uses one or more threads provided by the application.

The ConnectionOptions class provides a factory for `BackgroundThreads`,
for those (we expect few) applications that will want to control the
background threads.
@coryan coryan marked this pull request as ready for review October 15, 2019 00:08
* Connections need to perform background work on behalf of the application.
* Normally they just create a background thread and a `CompletionQueue` for
* this work, but the application may need more fine-grained control of their
* threads. In this case the application can provide the
Copy link
Contributor

Choose a reason for hiding this comment

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

"can provide the" ??

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Fixed.

virtual grpc_utils::CompletionQueue cq() const = 0;

/// Terminate any automatically created threads.
virtual void Shutdown() = 0;
Copy link
Contributor

Choose a reason for hiding this comment

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

Does Shutdown() need to exist as a part of this interface, or can a subclass just do the shutdown work in their destructor if there is any?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I am not sure. I think we will want to shut it down explicitly. But let's be conservative, I have removed the member function, we can always add it later if we really need it.


using BackgroundThreadsFactory =
std::function<std::unique_ptr<BackgroundThreads>()>;
BackgroundThreadsFactory background_threads_factory() {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm not sure I understand how to use this method. It looks like every call to this getter will return a factory that, when invoked, will create a new "BackgroundThread", and by default, will use a new CompletionQueue. Is that right?

Would it be good to just expose access to a single CompletionQueue instance that everyone can use? But honestly, maybe I'm just not understanding how this works.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure I understand how to use this method. It looks like every call to this getter will return a factory that, when invoked, will create a new "BackgroundThread", and by default, will use a new CompletionQueue. Is that right?

Yes.

Would it be good to just expose access to a single CompletionQueue instance that everyone can use? But honestly, maybe I'm just not understanding how this works.

I think we decided to tie the lifetime of the automatically created threads to the lifetime of the spanner::*Connection object. That means the *Connection needs to know if it creates a thread and completion queue, and if it does create them it needs to shutdown the completion queue and join the thread in its destructor. All those ifs suggested that this was a strategy given to the *Connection object.

In other words, we need to return something more than just the CompletionQueue, we need either (a) a thing that creates (when needed) the background thread for you, or (b) a bool that tells you if you should create a thread.

I went with option (a) because it seems wasteful to have every spanner::*Connection implement the "If I was asked to create a thread do this, otherwise do that".

@coryan
Copy link
Contributor Author

coryan commented Oct 17, 2019

PTAL

@coryan coryan merged commit 3379dc0 into googleapis:master Oct 17, 2019
@coryan coryan deleted the introduce-completion-queue-in-client branch October 17, 2019 14:20
devjgm pushed a commit to devjgm/google-cloud-cpp that referenced this pull request May 7, 2020
…-cloud-cpp-spanner#955)

This change introduces an interface to represent the background
thread(s) used by a connection. I included two implementations in this
PR, one that automatically creates a single background thread, and
another that uses one or more threads provided by the application.

The ConnectionOptions class provides a factory for `BackgroundThreads`,
for those (we expect few) applications that will want to control the
background threads.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Consider using a CompletionQueue for background operations.
4 participants