Skip to content

Annotate BatchStatement, Statement, SimpleStatement methods with CheckReturnValue #1607

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

Merged
merged 1 commit into from
Sep 16, 2024

Conversation

akhaku
Copy link
Contributor

@akhaku akhaku commented Sep 30, 2022

Since the driver's default implementation is for
BatchStatement#add* methods to be immutable, we should annotate those methods with @CheckReturnValue

@akhaku
Copy link
Contributor Author

akhaku commented Sep 30, 2022

Looks like I need to make changes to revapi.json for the build to be happy. Holding off on that until I get a 👍 or 👎 on making this change in general. The only reason I can think of for not adding these annotations is because, from the docs:

The driver's built-in implementation is immutable, and returns a new instance from this method. However custom implementations may choose to be mutable and return the same instance.

however similar documentation exists on methods like Statement#setExecutionProfileName but those methods are already annotated with @CheckReturnValue

Hm also it probably makes sense to add this on SimpleStatement#setQuery etc too... I'll wait to hear back on this first though.

@absurdfarce
Copy link
Contributor

Thanks for the PR @akhaku!

After thinking about this for just a bit my inclination is to continue down the path you outline here. I'm not completely convinced about the idea of annotating the interfaces rather than the concrete implementations (i.e. the things which are actually immutable). That said, as you point out without this change there is a difference between the semantics of BatchStatement and Statement... and that doesn't seem right. The benefit of bringing those two interfaces into alignment seems like a strong enough argument on it's own to move forward with this PR; we can perhaps debate afterwards whether we want the interface methods to be so annotated, but whatever path we choose we should be consistent about it across the interfaces.

Let me know if you need anything re: getting the revapi checks to pass.

Also, would you mind adding the annotation to the setBatchType() and setKeyspace() methods on BatchStatement as well? They seem to be in a very similar situation.

Thanks again!

@absurdfarce absurdfarce self-requested a review October 7, 2022 21:57
@adutra
Copy link
Contributor

adutra commented Oct 13, 2022

My 2c here is that you should add the missing annotation to all methods, and create exceptions in revapi.json.

I wouldn't care much about revapi here because even if it's indeed a breaking change stricto sensu, the worst that could happen is that this would break the build for people that have a strict static analyzer in place. But even if that happens, this is probably a good thing since it denotes a misusage of the driver API.

@adutra
Copy link
Contributor

adutra commented Oct 13, 2022

Hmm I might take that back sorry – at least partially :-)

I remember now: for SimpleStatement, BoundStatement and BatchStatement, the driver provides 2 implementations: an immutable one (declared in an internal package), and a mutable builder (declared in an API package).

The reason why we didn't annotate those interfaces with @CheckReturnValue is because of the builders, since they return the same instance.

I wouldn't mind adding the annotations though. It would make the usage of the immutable impls much easier for users; as for the builders, indeed users would need to recapture the returned object to make their IDEs happy, but this isn't incorrect either.

@akhaku
Copy link
Contributor Author

akhaku commented Oct 17, 2022

Thank you both for the feedback and comments! I've been a little busy lately so haven't had time to get back to this just yet. I'll go ahead and add the annotations to setBatchType() and setKeyspace() too.
Good point about the builders, I didn't realize they actually implement their statement types too. But yeah it's certainly safer to keep/add the missing annotations, makes it a little more difficult for a user to mess this up.

@akhaku akhaku force-pushed the checkReturnValue branch 2 times, most recently from 3199537 to d5e3cbe Compare October 22, 2022 23:10
@akhaku
Copy link
Contributor Author

akhaku commented Dec 16, 2022

just a rebase

@absurdfarce
Copy link
Contributor

Hey @akhaku, nice work here!

It seems like this addresses the outstanding issue with BatchStatement but this does now mean we have different semantics around the setters for that interface vs. the SimpleStatement interface. We should probably align those two so that the setters in SimpleStatement are also annotated in the same way.

I'm not sure I see how the builders are a problem in this case. BatchStatement.builder() returns an instance of BatchStatementBuilder; that class is mutable, but it doesn't implement the BatchStatement interface so there's no overlap there. BatchStatementBuilder.build() will produce an instance of BatchStatement but we re-use DefaultBatchStatement for that case. So it seems like the existing types would be okay if we annotate the interface.

It is true that this would force any custom implementations of the interface (which may or may not be immutable) to check return values for these methods. While this is somewhat annoying I'm not sure it's terribly onerous... and the benefits for the (much more common) default case seem to make it worthwhile.

@akhaku akhaku force-pushed the checkReturnValue branch from 1e890d1 to 0b69a4c Compare April 24, 2023 00:52
@akhaku
Copy link
Contributor Author

akhaku commented Apr 24, 2023

Just a rebase.
Regarding builders: gotcha, I was just commenting that I didn't realize the implementations returned by the builders are mutable by default. But I also didn't realize that they don't implement the BatchStatement interface, thanks.

Anyway, let me know if there's anything else I need to do here, otherwise please merge when ready!

@akhaku akhaku force-pushed the checkReturnValue branch from 0b69a4c to 47fdcfb Compare March 13, 2024 19:52
@akhaku
Copy link
Contributor Author

akhaku commented Mar 13, 2024

Thanks for the approval! Rebased to fix the merge conflict, please merge when ready.

@lukasz-antoniak
Copy link
Member

Shall we also add @CheckReturnValue to Statement#setNowInSeconds(int)? All Implementations are immutable and create new object.

@NonNull
@SuppressWarnings("unchecked")
default SelfT setNowInSeconds(int nowInSeconds) {
  return (SelfT) this;
}

@akhaku akhaku force-pushed the checkReturnValue branch from 47fdcfb to 251b166 Compare May 26, 2024 03:16
@akhaku
Copy link
Contributor Author

akhaku commented May 26, 2024

Sure, done!

@tolbertam tolbertam self-requested a review August 27, 2024 00:08
Copy link
Contributor

@tolbertam tolbertam left a comment

Choose a reason for hiding this comment

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

+1, i think this is good to merge as is, and 4.19.0 seems like a good time to do it!

I think @absurdfarce did still have a remaining point with regards to:

but this does now mean we have different semantics around the setters for that interface vs. the SimpleStatement interface. We should probably align those two so that the setters in SimpleStatement are also annotated in the same way.

For the same reason is there any reason why we wouldn't SimpleStatement: setQuery, setKeyspace, setPositionalValues, setNamedValuesWithIds, setNamedValues methods? It looks like we would want the annotation there for the same reason.

If you'd like to add those here that would be cool, but I also think we should be able to accept this PR as is as. I don't mind following up with a PR handling the SimpleStatement APIs if you are cool with it!

@absurdfarce
Copy link
Contributor

absurdfarce commented Sep 3, 2024

I agree with @tolbertam that we're there for BatchStatement and that 4.19.0 seems like a good place to add this functionality. But the resulting disconnect between the APIs for BatchStatement and SimpleStatement continue to trouble me; I'm not sure we want to release 4.19.0 with that disconnect in place. We could file a ticket to fix that later but that seems less than ideal; I'm not sure when that would actually happen and this release would go out with the disconnect in place.

@akhaku are you able to include that change here?

@akhaku
Copy link
Contributor Author

akhaku commented Sep 16, 2024

Fair enough, yeah updated with the suggested changes to SimpleStatement too 👍 and rebased as well

@akhaku akhaku changed the title Annotate BatchStatement methods with CheckReturnValue Annotate BatchStatement, Statement, SimpleStatement methods with CheckReturnValue Sep 16, 2024
@akhaku
Copy link
Contributor Author

akhaku commented Sep 16, 2024

Fixed a couple missed revapi changes and updated commit message with a more up-to-date description. Once I get that second +1 I'll update the commit message with the reviewers to get it ready to merge.

@absurdfarce
Copy link
Contributor

I've got a Jenkins run for your latest update running right now @akhaku. Assuming there aren't any regressions there (and I don't expect there will be) your second +1 will be en route shortly.

@absurdfarce
Copy link
Contributor

Okay, Jenkins run completed. Only failure was ContinuousPagingIT and it's known to have some issues (JAVA-2073). @akhaku you have your second +1 so if you can make the changes to the commit message we're all set here!

…kReturnValue

Since the driver's default implementation is for
BatchStatement and SimpleStatement methods to be immutable,
we should annotate those methods with @CheckReturnValue.
Statement#setNowInSeconds implementations are immutable so
annotate that too.

patch by Ammar Khaku; reviewed by Andy Tolbert and Bret McGuire for PR 1607
@akhaku
Copy link
Contributor Author

akhaku commented Sep 16, 2024

Thanks, commit message updated, ready to merge

@absurdfarce
Copy link
Contributor

Many thanks @akhaku!

#ThisIsHappening!

@absurdfarce absurdfarce merged commit be6f31d into apache:4.x Sep 16, 2024
absurdfarce pushed a commit that referenced this pull request Sep 16, 2024
…kReturnValue

Since the driver's default implementation is for
BatchStatement and SimpleStatement methods to be immutable,
we should annotate those methods with @CheckReturnValue.
Statement#setNowInSeconds implementations are immutable so
annotate that too.

patch by Ammar Khaku; reviewed by Andy Tolbert and Bret McGuire
reference: #1607
dkropachev added a commit to scylladb/java-driver that referenced this pull request Mar 19, 2025
* CASSANDRA-19635: Run integration tests with C* 5.x

patch by Lukasz Antoniak; reviewed by Andy Tolbert, and Bret McGuire for CASSANDRA-19635

* CASSANDRA-19635: Configure Jenkins to run integration tests with C* 5.x

patch by Lukasz Antoniak; reviewed by Bret McGuire for CASSANDRA-19635

* update badge URL to org.apache.cassandra/java-driver-core

* Limit calls to Conversions.resolveExecutionProfile

Those repeated calls account for a non-negligible portion of my application
CPU (0.6%) and can definitly be a final field so that it gets resolved only
once per CqlRequestHandler.

patch by Benoit Tellier; reviewed by Andy Tolbert, and Bret McGuire
reference: apache#1623

* autolink JIRA tickets in commit messages

patch by Stefan Miklosovic; reviewed by Michael Semb Wever for CASSANDRA-19854

* Don't return empty routing key when partition key is unbound

DefaultBoundStatement#getRoutingKey has logic to infer the
routing key when no one has explicitly called setRoutingKey
or otherwise set the routing key on the statement.
It however doesn't check for cases where nothing has been
bound yet on the statement.
This causes more problems if the user decides to get a
BoundStatementBuilder from the PreparedStatement, set some
fields on it, and then copy it by constructing new
BoundStatementBuilder objects with the BoundStatement as a
parameter, since the empty ByteBuffer gets copied to all
bound statements, resulting in all requests being targeted
to the same Cassandra node in a token-aware load balancing
policy.

patch by Ammar Khaku; reviewed by Andy Tolbert, and Bret McGuire
reference: apache#1620

* JAVA-3167: CompletableFutures.allSuccessful() may return never completed future

patch by Lukasz Antoniak; reviewed by Andy Tolbert, and Bret McGuire for JAVA-3167

* ninja-fix Various test fixes

* Run integration tests with DSE 6.9.0

patch by Lukasz Antoniak; reviewed by Bret McGuire
reference: apache#1955

* JAVA-3117: Call CcmCustomRule#after if CcmCustomRule#before fails to allow subsequent tests to run

patch by Henry Hughes; reviewed by Alexandre Dutra and Andy Tolbert for JAVA-3117

* JAVA-3149: Support request cancellation in request throttler
patch by Lukasz Antoniak; reviewed by Andy Tolbert and Chris Lohfink for JAVA-3149

* Fix C* 3.0 tests failing on Jenkins
patch by Lukasz Antoniak; reviewed by Bret McGuire
reference: apache#1939

* Reduce lock held duration in ConcurrencyLimitingRequestThrottler

It might take some (small) time for callback handling when the
throttler request proceeds to submission.

Before this change, the throttler proceed request will happen while
holding the lock, preventing other tasks from proceeding when there is
spare capacity and even preventing tasks from enqueuing until the
callback completes.

By tracking the expected outcome, we can perform the callback outside
of the lock. This means that request registration and submission can
proceed even when a long callback is being processed.

patch by Jason Koch; Reviewed by Andy Tolbert and Chris Lohfink for CASSANDRA-19922

* Annotate BatchStatement, Statement, SimpleStatement methods with CheckReturnValue

Since the driver's default implementation is for
BatchStatement and SimpleStatement methods to be immutable,
we should annotate those methods with @CheckReturnValue.
Statement#setNowInSeconds implementations are immutable so
annotate that too.

patch by Ammar Khaku; reviewed by Andy Tolbert and Bret McGuire
reference: apache#1607

* Remove "beta" support for Java17 from docs

patch by Bret McGuire; reviewed by Andy Tolbert and Alexandre Dutra
reference: apache#1962

* Fix uncaught exception during graceful channel shutdown

after exceeding max orphan ids

patch by Christian Aistleitner; reviewed by Andy Tolbert, and Bret McGuire for apache#1938

* Build a public CI for Apache Cassandra Java Driver

 patch by Siyao (Jane) He; reviewed by Mick Semb Wever for CASSANDRA-19832

* CASSANDRA-19932: Allow to define extensions while creating table
patch by Lukasz Antoniak; reviewed by Bret McGuire and Chris Lohfink

* Fix DefaultSslEngineFactory missing null check on close

patch by Abe Ratnofsky; reviewed by Andy Tolbert and Chris Lohfink for CASSANDRA-20001

* Query builder support for NOT CQL syntax

patch by Bret McGuire; reviewed by Bret McGuire and Andy Tolbert for CASSANDRA-19930

* Fix CustomCcmRule to drop `CURRENT` flag no matter what

If super.after() throws an Exception `CURRENT` flag is never dropped
which leads next tests to fail with IllegalStateException("Attempting to use a Ccm rule while another is in use.  This is disallowed")

Patch by Dmitry Kropachev; reviewed by Andy Tolbert and Bret McGuire for JAVA-3117

* JAVA-3051: Memory leak

patch by Jane He; reviewed by Alexandre Dutra and Bret McGuire for JAVA-3051

* Automate latest Cassandra versions when running CI

 patch by Siyao (Jane) He; reviewed by Mick Semb Wever for CASSJAVA-25

* Refactor integration tests to support multiple C* distributions. Test with DataStax HCD 1.0.0

patch by Lukasz Antoniak; reviewed by Bret McGuire
reference: apache#1958

* Fix TableMetadata.describe() when containing a vector column

patch by Stefan Miklosovic; reviewed by Bret McGuire for CASSJAVA-2

* Move Apache Cassandra 5.x off of beta1 and remove some older Apache Cassandra versions.

patch by Bret McGuire; reviewed by Bret McGuire for CASSJAVA-54

* Update link to Jira to be CASSJAVA

Updating the link to Jira.

Previously we had a component in the CASSANDRA Jira project but now we have a project for each driver - in the case of Java, it's CASSJAVA.

Added CASSJAVA to .asf.yaml

patch by Jeremy Hanna; reviewed by Bret McGuire for CASSJAVA-61

* Move DataStax shaded Guava module into Java driver

patch by Lukasz Antoniak; reviewed by Alexandre Dutra and Bret McGuire for CASSJAVA-52

* JAVA-3057 Allow decoding a UDT that has more fields than expected

patch by Ammar Khaku; reviewed by Andy Tolbert and Bret McGuire
reference: apache#1635

* CASSJAVA-55 Remove setting "Host" header for metadata requests.

With some sysprops enabled this will actually be respected which completely borks Astra routing.

patch by Bret McGuire; reviewed by Alexandre Dutra and Bret McGuire for CASSJAVA-55

* JAVA-3118: Add support for vector data type in Schema Builder, QueryBuilder
patch by Jane He; reviewed by Mick Semb Wever and Bret McGuire for JAVA-3118
reference: apache#1931

* Upgrade Guava to 33.3.1-jre

patch by Lukasz Antoniak; reviewed by Alexandre Dutra and Bret McGuire for CASSJAVA-53

* Do not always cleanup Guava shaded module before packaging

* Revert "Do not always cleanup Guava shaded module before packaging"

This reverts commit 5be52ec.

* Conditionally compile shaded Guava module

* JAVA-3143: Extend driver vector support to arbitrary subtypes and fix handling of variable length types (OSS C* 5.0)

patch by Jane He; reviewed by Bret McGuire and João Reis
reference: apache#1952

* JAVA-3168 Copy node info for contact points on initial node refresh only from first match by endpoint

patch by Alex Sasnouskikh; reviewed by Andy Tolbert and Alexandre Dura for JAVA-3168

* JAVA-3055: Prevent PreparedStatement cache to be polluted if a request is cancelled.

There was a critical issue when the external code cancels a request, indeed the cached CompletableFuture will then always throw a CancellationException.
This may happens, for example, when used by reactive like Mono.zip or Mono.firstWithValue.

patch by Luc Boutier; reviewed by Alexandre Dutra and Bret McGuire
reference: apache#1757

* Expose a decorator for CqlPrepareAsyncProcessor cache rather than the ability to specify an
arbitrary cache from scratch.

Also bringing tests from apache#2003 forward
with a few minor changes due to this implementation

patch by Bret McGuire; reviewed by Bret McGuire and Andy Tolbert
reference: apache#2008

* ninja-fix Using shaded Guava classes for import in order to make OSGi class paths happy.

Major hat tip to Dmitry Konstantinov for the find here!

* Changelog updates for 4.19.0

* [maven-release-plugin] prepare release 4.19.0

* [maven-release-plugin] prepare for next development iteration

* Specify maven-clean-plugin version

Sets the version to 3.4.1 in parent pom.
Having it unspecified causes the following warning:
```
[WARNING] Some problems were encountered while building the effective model for com.scylladb:java-driver-guava-shaded:jar:4.19.0.0-SNAPSHOT
[WARNING] 'build.plugins.plugin.version' for org.apache.maven.plugins:maven-clean-plugin is missing. @ line 97, column 15
[WARNING]
[WARNING] It is highly recommended to fix these problems because they threaten the stability of your build.
[WARNING]
[WARNING] For this reason, future Maven versions might no longer support building such malformed projects.
[WARNING]
```

* Install guava-shaded before running core's compile in CI

Without this module available "Build" and "Unit tests" job fail with
"package <x> does not exist" or "cannot find symbol" pointing to
`[...].shaded.guava.[...]` packages.

* Remove exception catch in `prepared_stmt_metadata_update_loopholes_test`

Since incorporating "JAVA-3057 Allow decoding a UDT that has more fields than
expected" the asuumptions of removed check are no longer valid.

* Switch shaded guava's groupId in osgi-tests

Switches from `org.apache.cassandra` to `com.scylladb`
in `BundleOptions#commonBundles()`.

* Typo: increase line's loglevel in CcmBridge

---------

Co-authored-by: Lukasz Antoniak <[email protected]>
Co-authored-by: Brad Schoening <[email protected]>
Co-authored-by: Benoit Tellier <[email protected]>
Co-authored-by: Stefan Miklosovic <[email protected]>
Co-authored-by: Ammar Khaku <[email protected]>
Co-authored-by: absurdfarce <[email protected]>
Co-authored-by: Henry Hughes <[email protected]>
Co-authored-by: Jason Koch <[email protected]>
Co-authored-by: Christian Aistleitner <[email protected]>
Co-authored-by: janehe <[email protected]>
Co-authored-by: Abe Ratnofsky <[email protected]>
Co-authored-by: absurdfarce <[email protected]>
Co-authored-by: Dmitry Kropachev <[email protected]>
Co-authored-by: janehe <[email protected]>
Co-authored-by: Jeremy Hanna <[email protected]>
Co-authored-by: SiyaoIsHiding <[email protected]>
Co-authored-by: Alex Sasnouskikh <[email protected]>
Co-authored-by: Luc Boutier <[email protected]>
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.

6 participants