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

Add durations to connection pool events #1166

Merged
merged 8 commits into from
Aug 25, 2023
Merged

Conversation

stIncMale
Copy link
Member

@stIncMale stIncMale commented Aug 2, 2023

This PR implements the spec change mongodb/specifications#1448.

JAVA-5076

@stIncMale stIncMale marked this pull request as ready for review August 21, 2023 22:27
@stIncMale stIncMale requested review from rozza and katcharov August 21, 2023 22:27
Copy link
Member

@rozza rozza left a comment

Choose a reason for hiding this comment

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

Couple of comments / questions and nits

@@ -77,6 +99,7 @@ public ConnectionCheckOutFailedEvent(final ServerId serverId, final long operati
* @param serverId the server id
* @param reason the reason the connection check out failed
* @deprecated Prefer {@link #ConnectionCheckOutFailedEvent(ServerId, long, Reason)}
* If this constructor is used, then {@link #getOperationId()} is -1.
Copy link
Member

Choose a reason for hiding this comment

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

Suggestion: If expanding out the defaults in the java docs then also include:

and {@link #getElapsedTime(TimeUnit)} is 0.

(This applies to all deprecated constructors with a default operation id)

Copy link
Member Author

Choose a reason for hiding this comment

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

I deliberately did not specify anything about getElapsedTime when documenting this constructor. The idea is that when we deprecate a constructor and introduce a new one, we should only update the documentation for the deprecated constructor and write the documentation for the new one. The reason behind this approach is that we are not going to remember and update all previous constructors each time we introduce a new one, which will lead to weird inconsistent documentation.

When we say Prefer {@link ...(ServerId, long, Reason, long)}. If this constructor is used, then {@link #getElapsedTime(TimeUnit)} is 0., a reader sees that the only difference between the preferred constructor and the one he looks at is a single parameter elapsedTimeNanos, and the documentation explains what value the current constructor uses given that it does not accept elapsedTimeNanos from a user.

Similarly, when we say Prefer {@link ...(ServerId, long, Reason)}. If this constructor is used, then {@link #getOperationId()} is -1., a reader sees that the only difference between the preferred constructor and the one he looks at is a single parameter operationId, and the documentation explains what value the current constructor uses given that it does not accept operationId from a user.

The same goes about the preferred constructors. When we introduce a new constructor, the preferred one specified in all previously deprecated constructors is not replaced with the new constructor. It stays unchanged, thus forming a chain of preference, that leads a reader from any constructor to a more and more preferred one. The chain ends with the non-deprecated constructor.

Given this description of the approach and the reason behind it (both are in bold above), do you still want the docs for all previous constructors to be updated when a new one is introduced?

Copy link
Member

@rozza rozza Aug 24, 2023

Choose a reason for hiding this comment

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

I can live with that 👍

@stIncMale stIncMale requested a review from rozza August 24, 2023 03:32
Copy link
Member

@rozza rozza left a comment

Choose a reason for hiding this comment

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

LGTM

private void connectionCheckoutStarted(final OperationContext operationContext) {

/**
* @return A {@link TimePoint} after executing {@link ConnectionPoolListener#connectionCheckOutStarted(ConnectionCheckOutStartedEvent)}.
Copy link
Member

Choose a reason for hiding this comment

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

👍

Copy link
Contributor

@katcharov katcharov left a comment

Choose a reason for hiding this comment

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

Code looks nice and straightforward, just doc clarifications.

Comment on lines +147 to +148
* This duration does not currently include the time to deliver the {@link ConnectionCheckOutStartedEvent}.
* Subject to change.</p>
Copy link
Contributor

Choose a reason for hiding this comment

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

getElapsedTime. Just curious, in the spec, what you said about user code (which I think referred to this) seemed right. What is the reason this might change?

Copy link
Member Author

Choose a reason for hiding this comment

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

🤷‍♂️ Maybe users will request for that, maybe something else I can't anticipate comes up. There is an opportunity to allow for a future change, and I prefer to take it.

Copy link
Contributor

Choose a reason for hiding this comment

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

When we say "Subject to change", it seems to negate the documented behaviour immediately preceding, since users cannot rely on it. This reminded me of @Beta. I also thought to search for the string "Subject to change" to see if we take this approach elsewhere, and the one result was:

APIs marked with the `@Beta` annotation at the class or method level are subject to change.

For any API we do not consider Beta, I think we should either avoid documenting anything that is subject to change (in cases where the external behaviour is trivial or irrelevant to users), or commit to a behaviour. My opinion is that committing is preferable, assuming it is reasonable for a user to ask "but does this include user code"?

Copy link
Member Author

Choose a reason for hiding this comment

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

"Subject to change", it seems to negate the documented behaviour immediately preceding, since users cannot rely on it.

We could say "we don't provide any guarantees on whether this duration includes the time to deliver ...". Instead, we give users more information: we document the current behavior (which enables a user to understand why his Thread.sleep(1_000) in a listener does not affect the duration reported in some events), but don't guarantee it will stay the same. Also, because the current behavior is documented, users know that if it is changed, the change will be visible in the documentation.

For any API we do not consider Beta, I think we should either avoid documenting anything that is subject to change

@Beta is about API changes, which is not what we are talking about here.

My opinion is that committing is preferable, assuming it is reasonable for a user to ask "but does this include user code"

  1. This PR implements the spec requirement "The driver MUST document this behavior as well as explicitly warn users that the behavior may change in the future". Are you require the spec to be re-considered? If yes, is this concern a PR blocker? Note that if a DRIVERS ticket is created, and the spec is changed as a result, incorporating such a change in the Java driver will not break compatibility.
  2. assuming it is reasonable for a user to ask "but does this include user code" - I don't understand this part. Could you explain it?

Copy link
Contributor

Choose a reason for hiding this comment

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

Described behaviour is rightly taken by users to be part of the public API. Some public behaviour might be tentative ("subject to change"), but my view is that all such instances in the driver should be marked with @Beta, and that this is done with the expectation that we think the present design is right, and will "soon" be removed from Beta. I do think it is a mistake for any non-beta spec to require drivers to mark public behaviour as tentative.

The original wording was describing public behaviour, however, I believe you are proposing that we might instead state this behaviour but clarify that it is non-public. I don't think we (or others) should describe implementation details, especially without a compelling reason. Otherwise, we might include many internal hints and tips in our docs.

So:

  1. If public behaviour is "subject to change", it should be marked Beta, which is not applicable here.
  2. Non-public behaviour is inherently "subject to change", but I think we should not mention internal behaviour.

My opinion is that you made the right call in excluding user code, and that we should publicly commit to that behaviour. I do not mind merging and changing this later via tickets, if that is more convenient.

stIncMale and others added 2 commits August 24, 2023 14:22
Co-authored-by: Maxim Katcharov <maxim.katcharov@mongodb.com>
@stIncMale stIncMale requested a review from katcharov August 24, 2023 20:49
Copy link
Contributor

@katcharov katcharov left a comment

Choose a reason for hiding this comment

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

Resolved some, still discussing others.

@stIncMale stIncMale requested a review from katcharov August 25, 2023 19:53
JAVA-5076
Copy link
Contributor

@katcharov katcharov left a comment

Choose a reason for hiding this comment

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

Approved, and created https://jira.mongodb.org/browse/DRIVERS-2707 for the minor spec change.

JAVA-5076
@stIncMale stIncMale merged commit 2fa9f49 into mongodb:master Aug 25, 2023
@stIncMale stIncMale deleted the JAVA-5076 branch August 25, 2023 23:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants