Remove reflection and augment the SynchronousNonBlockingStepExecution#executorService#1139
Remove reflection and augment the SynchronousNonBlockingStepExecution#executorService#1139jgreffe wants to merge 14 commits intojenkinsci:mainfrom
SynchronousNonBlockingStepExecution#executorService#1139Conversation
…n#executorService`
SynchronousNonBlockingStepExecution#executorService
src/test/java/io/jenkins/plugins/opentelemetry/JenkinsOtelPluginIntegrationTest.java
Outdated
Show resolved
Hide resolved
| public class StepExecutionInstrumentationInitializer implements OpenTelemetryLifecycleListener { | ||
|
|
||
| final static Logger logger = Logger.getLogger(StepExecutionInstrumentationInitializer.class.getName()); | ||
| public class StepExecutionInstrumentationInitializer |
There was a problem hiding this comment.
Note that this now happens unconditionally when the plugin is installed, not just when OTel is configured. I think that's ok and Context.taskWrapping will just be a no-op if the plugin isn't configured, but can you check to confirm?
The fact that SynchronousNonBlockingStepExecution.executorService is only initialized once though means that this won't work when the OTel plugin is installed dynamically. Maybe that's ok, but it would probably need to be documented. We could probably make things work for dynamic installations too if necessary, but it would be more complicated.
There was a problem hiding this comment.
any reason to change the signature of the class https://github.com/jenkinsci/opentelemetry-api-plugin/blob/main/src/main/java/io/jenkins/plugins/opentelemetry/api/OpenTelemetryLifecycleListener.java
There was a problem hiding this comment.
The signature has changed because the new extension point in workflow-step-api is unrelated to OpenTelemetryLifecycleListener. It applies unconditionally, which is why Julien added JenkinsOtelPluginNoConfigurationTest, to show that things work ok when this plugin is installed but not configured because Context.taskWrapping is simply a no-op in that case.
We could keep OpenTelemetryLifecycleListener in the signature here, but the afterConfiguration method would not do anything. The new upstream API does not allow dynamic reconfiguration of the ExecutorService (this is related to the issue with dynamic plugin installations I mention above).
If it's critical to support context propagation for synchronous steps after dynamic installations of the OTel plugin, we can probably make it work, but the API would need to be more complicated.
There was a problem hiding this comment.
@kuisathaverat I understand you want to wait to review this PR until it is in review, but we are introducing the upstream API specifically to be able to remove the existing reflection in this class, and there are no other expected consumers. We don't want to release the new API until we know that you are generally ok with how it works. Can you please review this comment thread when you have some time and let us know if you are ok with the general idea of the change?
This comment mentions a limitation of the change, which I want to know if you are ok with or not. We can likely adapt the API to avoid this limitation, but it will make things a bit more complicated.
This comment explains the reason for the signature change.
src/test/java/io/jenkins/plugins/opentelemetry/JenkinsOtelPluginNoConfigurationTest.java
Show resolved
Hide resolved
Signed-off-by: Julien Greffe <jgreffe@cloudbees.com>
Signed-off-by: Julien Greffe <jgreffe@cloudbees.com>
pom.xml
Outdated
| <dependency> | ||
| <groupId>org.jenkins-ci.plugins.workflow</groupId> | ||
| <artifactId>workflow-step-api</artifactId> | ||
| <version>705.vd44f505b_0c5b_</version> |
There was a problem hiding this comment.
this is a test dependency only
There was a problem hiding this comment.
@kuisathaverat Do you mean that you think this should be test scope, or that this is an incremental version of the plugin and we need to wait for a release?
I agree with the latter, @jgreffe in this kind of case where you introduce a new API and need to open a downstream PR to demonstrate the use case and make sure everything works, I recommend keeping the downstream PR in draft state and adding a comment above the incremental version like "TODO: Wait for release of <link to upstream PR>", so that no one accidentally merges the downstream PR too soon.
If you were talking about making this test scope though, opentelemetry currently has compile scope dependencies on workflow-job, workflow-cps, workflow-basic-steps, pipeline-model-definition, and various other plugins for Pipeline steps, all of which have either direct or transitive compile scope dependencies on workflow-step-api. workflow-step-api is at the bottom of the dependency chain of all the Pipeline-related plugins.
workflow-step-api is also is used directly in this plugin in a few ways, such as the step implementations in WithNewSpanStep, WithSpanAttributeStep, and WithSpanAttributesStep, and StepExecutionInstrumentationInitializer. Even if it's just for clarity, this plugin should probably have a direct dependency on workflow-step-api and workflow-api.
| public class StepExecutionInstrumentationInitializer implements OpenTelemetryLifecycleListener { | ||
|
|
||
| final static Logger logger = Logger.getLogger(StepExecutionInstrumentationInitializer.class.getName()); | ||
| public class StepExecutionInstrumentationInitializer |
There was a problem hiding this comment.
Can you give context of this change?
There was a problem hiding this comment.
@kuisathaverat Sorry, I thought someone had already contacted you to provide more context, but in general, CloudBees is looking into adding opentelemetry and opentelemetry-api to our CloudBees Assurance Program. As part of this process, we reviewed the codebase to find things that seemed problematic from a stability and maintenance standpoint. This is why CloudBees developers have been looking at removing reflection in this PR and in #1137 as well as investigating other issues such as #700, #1045, #1088, and #1151.
For this change in particular, I think the description here describes the goal - we just want to get rid of reflection. The description of jenkinsci/workflow-step-api-plugin#226 gives further context and lists some other approaches that we thought about briefly. If you think some other approach would be better, we'd be happy to look into it.
src/test/java/io/jenkins/plugins/opentelemetry/JenkinsOtelPluginIntegrationTest.java
Outdated
Show resolved
Hide resolved
|
I do not see a clear goal in these changes, but they are not related to the context given in the PR description, and there are a few changes that are not related to each other. Please, provide a proper description of the change. If there are different purposes, create different PRs; any style change should be put in a different PR. In short, I have a limited time for OSS, I want to use it in things that matter. |
kuisathaverat
left a comment
There was a problem hiding this comment.
Limit the changes to those described in the PR description
src/test/java/io/jenkins/plugins/opentelemetry/BaseIntegrationTest.java
Outdated
Show resolved
Hide resolved
src/test/java/io/jenkins/plugins/opentelemetry/BaseIntegrationTest.java
Outdated
Show resolved
Hide resolved
| * This test is similar to {@link JenkinsOtelPluginIntegrationTest#testSpanContextPropagationSynchronousNonBlockingTestStep()} | ||
| */ | ||
| @Test | ||
| public void test_noOp_when_not_configured() throws Exception { |
There was a problem hiding this comment.
camelcase is not the name convention used in the plugin
src/test/java/io/jenkins/plugins/opentelemetry/JenkinsOtelPluginNoConfigurationTest.java
Outdated
Show resolved
Hide resolved
.../java/io/jenkins/plugins/opentelemetry/init/StepExecutionInstrumentationInitializerTest.java
Outdated
Show resolved
Hide resolved
.../java/io/jenkins/plugins/opentelemetry/init/StepExecutionInstrumentationInitializerTest.java
Outdated
Show resolved
Hide resolved
| /** | ||
| * As the JVM and classes are loaded only once for the whole test, {@link SynchronousNonBlockingStepExecution#getExecutorService()} augments only once. The current boolean keeps track of the augmentation status. | ||
| */ | ||
| private static boolean augmented = false; |
There was a problem hiding this comment.
I am not sure what the goal of this boolean; it depends on the order of execution of the test, and it will be false/true when the test arrives at the call of checkAugmentation, I mean you have test A and B both call checkAugmentation, and augmented is false when the class is intanciated. If the test A run calls checkAugmentation with augmented=false and changes the value to true, the assert passes. Then, the test B will call checkAugmentation with augmented=true. If you invert the order of the test (B then A), B will call checkAugmentation with augmented=false and A will call checkAugmentation with augmented=true that's completely the opposite.
There was a problem hiding this comment.
Yes, it's the purpose of this boolean, we just want to check augmentation happened once.
There was a problem hiding this comment.
I think if we want to test that the augmentation only happens once, we should do it in workflow-step-api, since that plugin is responsible for the logic that results in it only happening once.
For this class, only keeping testStandardPipeline should be good enough to demonstrate synchronous steps are not broken when OTel is installed but not configured. The other tests seem ok to delete.
There was a problem hiding this comment.
And upstream jenkinsci/workflow-step-api-plugin@2947eae
...main/java/io/jenkins/plugins/opentelemetry/init/StepExecutionInstrumentationInitializer.java
Show resolved
Hide resolved
Signed-off-by: Julien Greffe <jgreffe@cloudbees.com> # Conflicts: # pom.xml # src/main/java/io/jenkins/plugins/opentelemetry/init/StepExecutionInstrumentationInitializer.java # src/test/java/io/jenkins/plugins/opentelemetry/BaseIntegrationTest.java # src/test/java/io/jenkins/plugins/opentelemetry/JenkinsOtelPluginIntegrationTest.java # src/test/java/io/jenkins/plugins/opentelemetry/init/StepExecutionInstrumentationInitializerTest.java
Signed-off-by: Julien Greffe <jgreffe@cloudbees.com>
src/test/java/io/jenkins/plugins/opentelemetry/JenkinsOtelPluginIntegrationTest.java
Show resolved
Hide resolved
.../java/io/jenkins/plugins/opentelemetry/init/StepExecutionInstrumentationInitializerTest.java
Outdated
Show resolved
Hide resolved
| /** | ||
| * As the JVM and classes are loaded only once for the whole test, {@link SynchronousNonBlockingStepExecution#getExecutorService()} augments only once. The current boolean keeps track of the augmentation status. | ||
| */ | ||
| private static boolean augmented = false; |
There was a problem hiding this comment.
I think if we want to test that the augmentation only happens once, we should do it in workflow-step-api, since that plugin is responsible for the logic that results in it only happening once.
For this class, only keeping testStandardPipeline should be good enough to demonstrate synchronous steps are not broken when OTel is installed but not configured. The other tests seem ok to delete.
| public class StepExecutionInstrumentationInitializer implements OpenTelemetryLifecycleListener { | ||
|
|
||
| final static Logger logger = Logger.getLogger(StepExecutionInstrumentationInitializer.class.getName()); | ||
| public class StepExecutionInstrumentationInitializer |
There was a problem hiding this comment.
The signature has changed because the new extension point in workflow-step-api is unrelated to OpenTelemetryLifecycleListener. It applies unconditionally, which is why Julien added JenkinsOtelPluginNoConfigurationTest, to show that things work ok when this plugin is installed but not configured because Context.taskWrapping is simply a no-op in that case.
We could keep OpenTelemetryLifecycleListener in the signature here, but the afterConfiguration method would not do anything. The new upstream API does not allow dynamic reconfiguration of the ExecutorService (this is related to the issue with dynamic plugin installations I mention above).
If it's critical to support context propagation for synchronous steps after dynamic installations of the OTel plugin, we can probably make it work, but the API would need to be more complicated.
...main/java/io/jenkins/plugins/opentelemetry/init/StepExecutionInstrumentationInitializer.java
Show resolved
Hide resolved
|
I will wait for the PR to be in review to take a new look at it. |
Signed-off-by: Julien Greffe <jgreffe@cloudbees.com>
Signed-off-by: Julien Greffe <jgreffe@cloudbees.com>
Signed-off-by: Julien Greffe <jgreffe@cloudbees.com>
Signed-off-by: Julien Greffe <jgreffe@cloudbees.com>
…into jgreffe/avoid-steps-reflection
Code refactoring to avoid using reflection against
workflow-step-api-pluginUses the new API provided by jenkinsci/workflow-step-api-plugin#226
Testing done
Submitter checklist