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

feat(pubsub): introduce PublisherOptionList (g::c::Options) #7273

Closed

Conversation

dbolduc
Copy link
Member

@dbolduc dbolduc commented Sep 3, 2021

Start of the work for #6306

Some choices:

  1. used a private enum for FullPublisherAction. I considered having 3 bool options, which might conflict, but ultimately decided that although the enum is verbose, it is clearest. It is also consistent with this in spanner. (I could use a check on doxygen comments for enum values)
  2. default values are just hardcoded in (instead of using constants which have hardcoded values). This is not what was done in bigtable, but it is what was done in spanner.
  3. test for equality of default values instead of testing that default values are > 0. This is not what is done in publisher_options_test, but I personally prefer it.
  4. forward declaration of PublisherOptions is ugly. Not sure how to avoid it though.

This change is Reviewable

@product-auto-label product-auto-label bot added the api: pubsub Issues related to the Pub/Sub API. label Sep 3, 2021
@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Sep 3, 2021
@google-cloud-cpp-bot
Copy link
Collaborator

Google Cloud Build Logs
For commit: 60d85e61d1216c6b9641e761f920962fe9e77bc9

ℹ️ NOTE: Kokoro logs are linked from "Details" below.

@codecov
Copy link

codecov bot commented Sep 3, 2021

Codecov Report

Merging #7273 (56efd26) into main (6750048) will increase coverage by 0.02%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #7273      +/-   ##
==========================================
+ Coverage   94.34%   94.36%   +0.02%     
==========================================
  Files        1317     1320       +3     
  Lines      114594   114688      +94     
==========================================
+ Hits       108108   108226     +118     
+ Misses       6486     6462      -24     
Impacted Files Coverage Δ
google/cloud/pubsub/internal/defaults.cc 100.00% <100.00%> (ø)
google/cloud/pubsub/internal/defaults_test.cc 100.00% <100.00%> (ø)
...ernal/flow_controlled_publisher_connection_test.cc 100.00% <100.00%> (+1.51%) ⬆️
google/cloud/pubsub/publisher.cc 100.00% <100.00%> (ø)
google/cloud/pubsub/publisher_options.cc 100.00% <100.00%> (ø)
google/cloud/pubsub/publisher_options.h 100.00% <100.00%> (ø)
google/cloud/pubsub/publisher_options_test.cc 100.00% <100.00%> (+2.22%) ⬆️
...cloud/pubsub/internal/subscription_session_test.cc 98.27% <0.00%> (-0.25%) ⬇️
google/cloud/completion_queue_test.cc 96.95% <0.00%> (-0.20%) ⬇️
... and 10 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 6750048...56efd26. Read the comment docs.

@dbolduc dbolduc changed the title refactor(pubsub): implement PublisherOptions using g::c::Options feat(pubsub): introduce PublisherOptionList (g::c::Options) Sep 4, 2021
@google-cloud-cpp-bot
Copy link
Collaborator

Google Cloud Build Logs
For commit: 56efd264e18827558c840f9194f6254833af9d2c

ℹ️ NOTE: Kokoro logs are linked from "Details" below.

@dbolduc dbolduc marked this pull request as ready for review September 4, 2021 04:58
@dbolduc dbolduc requested a review from a team as a code owner September 4, 2021 04:58
* @note Application developers should keep in mind that Cloud Pub/Sub
* sets [limits][pubsub-quota-link] on the size of a batch (1,000 messages)
* The library makes no attempt to validate the value provided in this
* function.
Copy link
Contributor

Choose a reason for hiding this comment

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

s/function/option/ ?

* @note Application developers should keep in mind that Cloud Pub/Sub
* sets [limits][pubsub-quota-link] on the size of a batch (10MB). The
* library makes no attempt to validate the value provided in this
* function.
Copy link
Contributor

Choose a reason for hiding this comment

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

Ditto.

};

/// Actions taken by a full publisher.
enum class FullPublisherAction {
Copy link
Contributor

Choose a reason for hiding this comment

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

Hmmm... I was trying to not make these enums public, I cannot recall why. Maybe because I hate enum:

  • They are the devil to evolve
  • They are a code smell for "somebody is using switch when they should be using virtual functions"

But I cannot recall why I did not want them in this case.... Can we hide them in an opaque type?

class FullPublisherAction {
 public:
   // maybe == and operator!=
  static FullPublisherAction BlockIfFull() { return FullPublisherAction(kBlocks); }
  static FullPublisherAction RejectIfFull() { return FullPublisherAction(kRejects); }
  static FullPublisherAction None() { return FullPublisherAction(kIgnored); }

 private:
   enum Discriminant { kIgnored, kRejects, kBlocks };
   explicit FullPublisherAction(Discriminant d) : discriminant_(d) {}
   friend ... internal::DoStuff(FullPublisherAction a);
};

Copy link
Contributor

Choose a reason for hiding this comment

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

I am not convinced that a public enum is a bad idea, but I am not convinced it is a good idea. Can you provide an argument one way or the other?

Copy link
Member Author

Choose a reason for hiding this comment

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

So quick thoughts are that

  1. user code doesn't change much either way.
opts.set<FullPublisherActionOption>(FullPublisherAction::kBlockIfFull); // or kBlocks
// vs.
opts.set<FullPublisherActionOption>(FullPublisherAction::BlockIfFull());
  1. Spanner has a similar enum

    /// Action to take when the session pool is exhausted.
    enum class ActionOnExhaustion { kBlock, kFail };
    /**
    * Option for `google::cloud::Options` to set the action to take when
    * attempting to allocate a session when the pool is exhausted.
    */
    struct SessionPoolActionOnExhaustionOption {
    using Type = spanner::ActionOnExhaustion;
    };

  2. I'm going to guess it's easier to deprecate a method from the class than it is to deprecate a value from the enum. Also it seems slightly better to grow a class by adding methods than by appending values to an enum.

  3. Currently, the value is used as an enum. Would it ever grow? For example something that could take in a callback? Like do generic user provided action when Publisher is full, instead of one of the three actions we have listed for you.

  4. the class is more complex for us to write. It is ever so slightly more complicated for a user to understand.

Copy link
Member Author

Choose a reason for hiding this comment

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

If there is an action to be taken, other than the ones we list, then the class makes sense. Here is a stupid one:

static FullPublisherAction RejectIfFullWithProbability(double p);

What might a real action be?

Copy link
Contributor

Choose a reason for hiding this comment

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

Let's go with the public enum.

@@ -46,7 +60,19 @@ inline namespace GOOGLE_CLOUD_CPP_PUBSUB_NS {
*/
class PublisherOptions {
public:
PublisherOptions() = default;
PublisherOptions() : PublisherOptions(Options{}) {}
/**
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: blank line before comment block

PublisherOptions)
Publisher::Publisher(
std::shared_ptr<PublisherConnection> connection,
PublisherOptions) // NOLINT(performance-unnecessary-value-param)
Copy link
Contributor

Choose a reason for hiding this comment

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

Q: do you know why this is needed now?

Copy link
Member Author

Choose a reason for hiding this comment

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

A: Honestly, no... clang-tidy yelled at me, so I changed it. (It also yelled at me to make the change in flow_controlled_publisher_connection_test.cc)

@dbolduc
Copy link
Member Author

dbolduc commented Sep 5, 2021

I wanted to get this done but I do not have the patience to set up a development workstation on my windows laptop right now. So I am temporarily closing this, to be reopened in one week.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: pubsub Issues related to the Pub/Sub API. cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants