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

Renew connection in PostgresChannelMessageTableSubscriber only when invalid. #9111

Conversation

joshiste
Copy link
Contributor

@joshiste joshiste commented May 3, 2024

No description provided.

Copy link
Member

@artembilan artembilan left a comment

Choose a reason for hiding this comment

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

I see that this is an evolution of your previous change for the #9061 .

Does this conn.isValid(1) still report OK in case of DB failover ?

Thanks

connectionLatch.countDown();
new Thread(() -> {
try {
Thread.sleep(3000);
Copy link
Member

Choose a reason for hiding this comment

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

I'm not very happy when we create unmanaged threads, even in tests.
Isn't there other way to achieve whatever is expected here?
I'm not sure, though, what is that we try to simulate with this separate thread...

Would you mind to elaborate the logic?

Thanks

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 added this to close the connection after 3 seconds so that the isValid() method returns false and the connection is renewed. Do you now a better way to wait and close the connection?

Copy link
Member

Choose a reason for hiding this comment

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

Right. 3 seconds is too much for our tests to perform.
We have like 5000 tests in the project. Now imagine if we don't care about the time on them.
How about just to have a connection to be closed immediately on a first call, so the next one would have it re-opened?
Instead of new thread and 3 seconds delay just have an AtomicBoolean flag.

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 don't think using an atomic flag would work here ... As I want the same connection to first succeed on the LISTEN call and then fail after some time. I most probably don't get your suggestion, cause I don't see how to achieve this with an AtomicBoolean....

Copy link
Member

Choose a reason for hiding this comment

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

Just changed your code to this and it still works:

		AtomicBoolean connectionCloseState = new AtomicBoolean();
		connectionSupplier.onGetConnection = conn -> {
			connectionLatch.countDown();
			if (connectionCloseState.compareAndSet(false, true)) {
				try {
					conn.close();
				}
				catch (Exception e) {
					//nop
				}
			}
		};

What do I miss?

@joshiste
Copy link
Contributor Author

joshiste commented May 5, 2024

Does this conn.isValid(1) still report OK in case of DB failover ?

In most cases it will report false, but if it would return true it would be ok to not renew the connection. From the JDBC javadoc:

Returns true if the connection has not been closed and is still valid. The driver shall submit a query on the connection or use some other mechanism that positively verifies the connection is still valid when this method is called.
The query submitted by the driver to validate the connection shall be executed in the context of the current transaction.

The Idea behind this PR is to renew the connection only when we need to.

connectionLatch.countDown();
new Thread(() -> {
try {
Thread.sleep(3000);
Copy link
Member

Choose a reason for hiding this comment

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

Right. 3 seconds is too much for our tests to perform.
We have like 5000 tests in the project. Now imagine if we don't care about the time on them.
How about just to have a connection to be closed immediately on a first call, so the next one would have it re-opened?
Instead of new thread and 3 seconds delay just have an AtomicBoolean flag.

Copy link
Member

@artembilan artembilan left a comment

Choose a reason for hiding this comment

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

If you are OK with my change to the test, I can merge it since I have it locally.
Thanks

connectionLatch.countDown();
new Thread(() -> {
try {
Thread.sleep(3000);
Copy link
Member

Choose a reason for hiding this comment

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

Just changed your code to this and it still works:

		AtomicBoolean connectionCloseState = new AtomicBoolean();
		connectionSupplier.onGetConnection = conn -> {
			connectionLatch.countDown();
			if (connectionCloseState.compareAndSet(false, true)) {
				try {
					conn.close();
				}
				catch (Exception e) {
					//nop
				}
			}
		};

What do I miss?

Copy link
Member

@artembilan artembilan left a comment

Choose a reason for hiding this comment

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

OK. Since you don't answer, I'm merging this with my correction.
We have to release today.
Feel free to follow up with other possible improvements afterwards.
Thanks

spring-builds pushed a commit that referenced this pull request May 21, 2024
Fixes: #9111

An evolution of the #9061: renew the connection only when we need to.

(cherry picked from commit da29e2d)
artembilan pushed a commit that referenced this pull request May 21, 2024
Fixes: #9111

An evolution of the #9061: renew the connection only when we need to.

(cherry picked from commit da29e2d)

# Conflicts:
#	spring-integration-jdbc/src/main/java/org/springframework/integration/jdbc/channel/PostgresChannelMessageTableSubscriber.java
@joshiste
Copy link
Contributor Author

OK. Since you don't answer, I'm merging this with my correction. We have to release today. Feel free to follow up with other possible improvements afterwards. Thanks

Ah yes sorry, was quite busy. Thanks for merging!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants