Skip to content

Add Spring Integration default poller auto-config #27992

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

Closed
wants to merge 4 commits into from

Conversation

artembilan
Copy link
Member

When polling consumers or source polling channel adapters
are used in Spring Integration applications, they require
some polling policy to be configured

  • Add some sensitive default bean PollerMetadata auto-configured
    bean which can be overridden by end-user or customized via
    respective newly added spring.integration.poller.* configuration
    properties

For reference a recent StackOverflow question:
https://stackoverflow.com/questions/69175808

When polling consumers or source polling channel adapters
are used in Spring Integration applications, they require
some polling policy to be configured

* Add some sensitive default bean `PollerMetadata` auto-configured
bean which can be overridden by end-user or customized via
respective newly added `spring.integration.poller.*` configuration
properties

For reference a recent StackOverflow question:
https://stackoverflow.com/questions/69175808
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Sep 14, 2021
@wilkinsona wilkinsona added type: enhancement A general enhancement and removed status: waiting-for-triage An issue we've not yet triaged labels Sep 15, 2021
@wilkinsona wilkinsona added this to the 2.6.x milestone Sep 15, 2021
Copy link
Member

@wilkinsona wilkinsona left a comment

Choose a reason for hiding this comment

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

Thanks for the PR, @artembilan. I've left a few comments for your consideration when you have a moment.

/**
* How long to wait for messages on poll.
*/
private Duration receiveTimeout;
Copy link
Member

Choose a reason for hiding this comment

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

This field could have a default value that matches PollerMetadata.DEFAULT_RECEIVE_TIMEOUT. That would then make the default available in auto-complete when configuring the property.

Copy link
Member Author

Choose a reason for hiding this comment

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

Thank you Andy for feedback!
If I recall correctly, you or Stéphane pointed us in the past that it is better to keep configuration properties beans free from target libraries dependencies, so I decided to go with that sensitive defaults which comes with a PollerMetadata instance and what could be changed in the past if we would use values over here instead of those constant references. If that is still OK, I can change it as you suggest to point to those PollerMetadata constants.
Or I can use their values directly for time being. That's in the case if we don't go with nulls as I have done now.

Copy link
Member

Choose a reason for hiding this comment

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

We typically duplicate the default without referencing anything in the library. We can then test that our default matches the library's default, as you have already done in this case.

/**
* Maximum of messages to poll per polling cycle.
*/
private Long maxMessagesPerPoll;
Copy link
Member

Choose a reason for hiding this comment

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

This field could have a default value that matches PollerMetadata.MAX_MESSAGES_UNBOUNDED. That would then make the default available in auto-complete when configuring the property.

private Duration initialDelay;

/**
* Cron expression for polling.
Copy link
Member

Choose a reason for hiding this comment

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

It would be good to document that cron, fixedRate, and fixedDelay are mutually exclusive.

Copy link
Member Author

@artembilan artembilan Sep 15, 2021

Choose a reason for hiding this comment

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

This is true.
In Stream Applications project we use @Validated feature to prevent ambiguity downstream and to avoid precedence as you pointed in the next comment: #27992 (comment).
The approach is like this: https://github.com/spring-cloud/stream-applications/blob/main/functions/consumer/log-consumer/src/main/java/org/springframework/cloud/fn/consumer/log/LogConsumerProperties.java#L57.
Since I don't see anything like that in Spring Boot by itself, I forgot to ask such a question when opened PR.

Thank you for reminder!
So, now let's discuss what is the best way to go.
I simply can validate exclusiveness in target code where I apply those properties, although it is still feels more nature to validate them on the configuration properties phase.
If you point me to something similar, I'll fix it ASAP

Copy link
Member

Choose a reason for hiding this comment

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

I've labeled this for discussion at a team meeting so that we can consider our options.

Copy link
Member

Choose a reason for hiding this comment

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

We're going to follow the precedent set by Framework's handling of @Scheduled and fail if more than one of cron, fixed-rate, and fixed-delay is set.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good. I can do that. Any particular advice where to do validation?
I can just have an Assert.state() in that PollerMetadata bean definition.
Although it is not clear why you are talking about precedence if we are going to reject ambiguity anyway.

Thanks

Copy link
Member

Choose a reason for hiding this comment

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

Doing it in the PollerMetadata @Bean method sounds good to me. Generally, we try to keep the properties classes themselves as free of logic as possible.

Although it is not clear why you are talking about precedence

I was talking about the precedent set by Framework in how it handles similar properties on @Scheduled. Nothing to do with which property takes precedence over another. That was an option, but we've decided to fail now.

private Duration fixedRate;

/**
* Polling initial delay.
Copy link
Member

Choose a reason for hiding this comment

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

It would be good to document that cron, fixedRate, and fixedDelay are mutually exclusive.

private Duration fixedDelay;

/**
* Polling rate period.
Copy link
Member

Choose a reason for hiding this comment

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

It would be good to document that cron, fixedRate, and fixedDelay are mutually exclusive.

Comment on lines 126 to 132
map.from(poller::getCron).whenHasText().as(CronTrigger::new).to(pollerMetadata::setTrigger);
map.from(poller.getFixedDelay() != null ? poller.getFixedDelay() : poller.getFixedRate())
.as(Duration::toMillis).as(PeriodicTrigger::new).as((trigger) -> {
map.from(poller::getInitialDelay).as(Duration::toMillis).to(trigger::setInitialDelay);
trigger.setFixedRate(poller.getFixedRate() != null);
return trigger;
}).to(pollerMetadata::setTrigger);
Copy link
Member

Choose a reason for hiding this comment

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

I wonder how we should handle the user setting more than one of cron, fixedDelay, and fixedRate. As things stand it looks like the order of precedence is fixedDelay, fixedRate, cron. Should we document this ordering, fail when more than one is configured, or something else?

Copy link
Member

Choose a reason for hiding this comment

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

We've decided to fail.

@wilkinsona wilkinsona added the for: team-meeting An issue we'd like to discuss as a team to make progress label Sep 15, 2021
* Document that `fixedDelay`, `fixedRate` and `cron` are mutually exclusive
@wilkinsona wilkinsona removed the for: team-meeting An issue we'd like to discuss as a team to make progress label Sep 17, 2021
`fixed-delay` & `fixed-rate` properties
wilkinsona pushed a commit to wilkinsona/spring-boot that referenced this pull request Sep 23, 2021
When polling consumers or source polling channel adapters are used in
Spring Integration applications, they require some polling policy to
be configured.

This comment auto-configures a PollerMetadata bean which customized
via newly added `spring.integration.poller.*` configuration
properties or overriden completely be user-defined bean.

See spring-projectsgh-27992
wilkinsona added a commit to wilkinsona/spring-boot that referenced this pull request Sep 23, 2021
philwebb pushed a commit that referenced this pull request Sep 23, 2021
When polling consumers or source polling channel adapters are used in
Spring Integration applications, they require some polling policy to
be configured.

This comment auto-configures a PollerMetadata bean which customized
via newly added `spring.integration.poller.*` configuration
properties or overriden completely be user-defined bean.

See gh-27992
philwebb added a commit that referenced this pull request Sep 23, 2021
See gh-27992

Co-authored-by: Phillip Webb <pwebb@vmware.com>
@philwebb philwebb closed this in 5bd34be Sep 23, 2021
@philwebb philwebb modified the milestones: 2.6.x, 2.6.0-M3 Sep 23, 2021
artembilan added a commit to artembilan/spring-cloud-stream that referenced this pull request Oct 7, 2021
Starting with Spring Boot `2.6`, the auto-configuration
for Spring Integration introduces `poller` properties.
The `DefaultPollerProperties` and its respective `ChannelBindingAutoConfiguration` are not needed any more.

* Add `PollerConfigEnvironmentPostProcessor` to remap deprecated
`spring.cloud.stream.poller` into respective `spring.integration.poller`
properties
* Mention in the docs a deprecation move and its replacement

Related to: spring-projects/spring-boot#27992
olegz pushed a commit to spring-cloud/spring-cloud-stream that referenced this pull request Oct 18, 2021
Starting with Spring Boot `2.6`, the auto-configuration
for Spring Integration introduces `poller` properties.
The `DefaultPollerProperties` and its respective `ChannelBindingAutoConfiguration` are not needed any more.

* Add `PollerConfigEnvironmentPostProcessor` to remap deprecated
`spring.cloud.stream.poller` into respective `spring.integration.poller`
properties
* Mention in the docs a deprecation move and its replacement

Related to: spring-projects/spring-boot#27992
Resolves #2233
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: enhancement A general enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants