Repository navigation
Async step timeouts - #1834
Async step timeouts#1834vkalapov wants to merge 7 commits into
Conversation
51adc0c to
f3efdb1
Compare
|
|
|
||
| @Override | ||
| public Duration getTimeout(ProcessContext context) { | ||
| return calculateTimeout(context, TimeoutType.BIND_SERVICE); |
There was a problem hiding this comment.
why checking a service key operation is using BIND_SERVICE instead of CREATE_SERVICE_KEY
|
|
||
| @Named("globalTimeoutSettingStep") | ||
| @Scope(BeanDefinition.SCOPE_PROTOTYPE) | ||
| public class GlobalTimeoutSettingStep extends SyncFlowableStep { |
There was a problem hiding this comment.
Use constructor injection
| return timeoutType.isModuleScoped() ? moduleTimeoutSources : serviceTimeoutSources; | ||
| } | ||
|
|
||
| public DeploymentDescriptor getDeploymentDescriptor(ProcessContext context, StepLogger stepLogger) { |
There was a problem hiding this comment.
Why TimeoutValueResolved has a method for getting the DeploymentDescriptor from context. This breaks single responsibility principle
| if (!timeoutType.isServiceScoped()) { | ||
| return false; | ||
| } |
There was a problem hiding this comment.
Why is this check needed for?
| String timeoutSeconds = timeout != null ? String.valueOf(timeout.toSeconds()) : "null"; | ||
| getStepLogger().debug(Messages.TIMEOUT_0_EQUALS_1_SECONDS_FROM_2, |
There was a problem hiding this comment.
Can we say the parameter is not set instead of logging 'null' strings?
| import org.cloudfoundry.multiapps.mta.model.Resource; | ||
|
|
||
| @Named | ||
| public class TimeoutServiceResourceNameResolver { |
There was a problem hiding this comment.
Is this used beyond tests?
| private interface TimeoutSource { | ||
| Optional<TimeoutResolution> resolve(ProcessContext context, TimeoutType timeoutType, StepLogger logger); |
There was a problem hiding this comment.
Why TimeoutSource has a resolve method? Rename to some resolver?
| return DurationUtil.parseDuration(timeout, timeoutParameterName, maxAllowedValue); | ||
| } | ||
|
|
||
| private Optional<Module> findModuleByAppName(DeploymentDescriptor descriptor, String appName) { |
There was a problem hiding this comment.
The module name and the app-name might not always match. Can we reuse some already existing method util instead of having another similar method?
| public record TimeoutResolution(Duration timeout, String parameterName) { | ||
| } | ||
|
|
||
| private final List<TimeoutSource> moduleTimeoutSources = List.of( |
There was a problem hiding this comment.
Isn't the whole logic a bit over engineered with all these lambdas and records?
| .filter(type -> originalParameters.containsKey(type.getProcessVariable() | ||
| .getName())) | ||
| .forEach(type -> targetParameters.put(type.getOperationParamsFlag() |
There was a problem hiding this comment.
What is the point of setting these variables to true if they are hardcoded in the enum while their default value is false?
f3efdb1 to
86d67e4
Compare
Introduce the vocabulary for configurable service operation timeouts: - SupportedParameters: resource-level (create-service-timeout, bind-service-timeout, create-service-key-timeout) and global-level (services-*) parameter names - Variables: the CLI-override process variables and the bind global fallback - CloudServiceInstanceExtended: resource-level timeout fields, populated by ServicesCloudModelBuilder from the service's mtad parameters - DurationUtil: parse and validate raw timeout values into Duration - Constants: fixed ceilings for delete-service, delete-service-key and unbind-service operations
Add the timeout resolution engine: - TimeoutType: declares, per operation, its parameter names, CLI process variable, maximum value, and (for services) how to read the timeout off the service instance - TimeoutValueResolver: resolves a timeout by priority — CLI process variable, then resource/service-object value, then global descriptor parameter, then the default. Bind additionally falls back to a pre-resolved global variable because its subprocess has no descriptor - TimeoutStepStateManager: tracks per-step elapsed time with correct reset semantics across retries and poll cycles
Wire the async steps to the resolver: - TimeoutAsyncFlowableStep: resolve and log the timeout, then enforce it via the step state manager on every execution - Create/Bind/CheckServiceBinding/CheckServiceKey steps resolve their configurable timeout from the resolver - Delete/DeleteServiceKey/Unbind steps adopt a fixed safety ceiling (previously unbounded) - ProcessDescriptorStep pre-resolves the global bind timeout into a process variable for the binding subprocess, which has no descriptor
Register the create-service, bind-service and create-service-key timeout parameters (with their integer conversion) in the deploy, blue-green, CTS and rollback metadata so they are accepted and converted to process variables. Update metadata tests accordingly.
ca7e8a6 to
50270b6
Compare
50270b6 to
7f1c661
Compare
| return Optional.empty(); | ||
| } | ||
| long seconds = number.longValue(); | ||
| return seconds > 0 ? Optional.of(Duration.ofSeconds(seconds)) : Optional.empty(); |
There was a problem hiding this comment.
In the method above we have max value, don't we need here also a max value?
| Variable<Duration> BIND_SERVICE_TIMEOUT_GLOBAL_FALLBACK = ImmutableSimpleVariable.<Duration> builder() | ||
| .name("servicesBindServiceTimeoutGlobalFallback") | ||
| .build(); |
There was a problem hiding this comment.
Do we need default value for this Variable
|



LMCROSSITXSADEPLOY-3322