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

feat(engine): Populating process instance id in jobs #4334

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

punitdarira
Copy link
Contributor

related to #4205

@punitdarira punitdarira marked this pull request as ready for review May 14, 2024 04:06
@punitdarira
Copy link
Contributor Author

@yanavasileva,
The AcquirableJobEntity does not contain a processDefinitionId field. Should we add a new field, or is the processDefinitionId set elsewhere? Additionally, could you explain how the job logs will be visible in the Historic Process Definition page and Job Log view once the processDefinitionId is set?

@yanavasileva
Copy link
Member

Hi @punitdarira,

Thank you for raising this pull request and showing interest in our product.

The AcquirableJobEntity does not contain a processDefinitionId field. Should we add a new field, or is the processDefinitionId set elsewhere?

Why you need the field there? The processDefinitionId field should be populated in a similar way to the JobEntity here: https://github.com/camunda/camunda-bpm-platform/pull/4334/files#diff-bbebf2d653092eaf76c21343a5d422db745c0f5ab55aeef084435be0e64ab11bR173-R175

Additionally, could you explain how the job logs will be visible in the Historic Process Definition page and Job Log view once the processDefinitionId is set?

In Cockpit, we display all job logs with the specific processDefinitionId. Once a job has set this id, the historic job log will inherit it, and out-of-the-box the entities will be populated in the mentioned page and view. No action is required for this comment.

Lastly, don't forget to cover the made changes with test cases.

Hope that helps you to continue with the contribution.

Best,
Yana

@punitdarira
Copy link
Contributor Author

Hi @punitdarira,

Thank you for raising this pull request and showing interest in our product.

The AcquirableJobEntity does not contain a processDefinitionId field. Should we add a new field, or is the processDefinitionId set elsewhere?

Why you need the field there? The processDefinitionId field should be populated in a similar way to the JobEntity here: https://github.com/camunda/camunda-bpm-platform/pull/4334/files#diff-bbebf2d653092eaf76c21343a5d422db745c0f5ab55aeef084435be0e64ab11bR173-R175

Additionally, could you explain how the job logs will be visible in the Historic Process Definition page and Job Log view once the processDefinitionId is set?

In Cockpit, we display all job logs with the specific processDefinitionId. Once a job has set this id, the historic job log will inherit it, and out-of-the-box the entities will be populated in the mentioned page and view. No action is required for this comment.

Lastly, don't forget to cover the made changes with test cases.

Hope that helps you to continue with the contribution.

Best, Yana

Hi Yana,
The process definitionId is already being set to the job-

job.setProcessDefinitionId(jobDefinition.getProcessDefinitionId());

The above line gets invoked from
org.camunda.bpm.engine.impl.batch.AbstractBatchJobHandler.createBatchJob(BatchEntity batch, ByteArrayEntity configuration)
Do we still need to set again in createJobEntities()?

Regarding tests, can you please guide whether we should go for new test file for AbstractBatchJobHandler where we simply mock or do we deploy a bpmn file in a test case and check whether instance and definition ids are set?

@yanavasileva
Copy link
Member

The process definitionId is already being set to the job

I missed that, however, in debug mode and in general the historic job logs doesn't inherit the process definition id from the batch job entity. At the moment, I can't say why is that. So we need to understand why and fix it eventually.

Regarding tests, can you please guide

I think we can add a test case(s) to existing classes that test batch execution. Here's an example of single invocation test for set variables we have at the moment: https://github.com/camunda/camunda-bpm-platform/blob/master/engine/src/test/java/org/camunda/bpm/engine/test/api/runtime/SetVariablesBatchTest.java#L673-L695.
examples of interesting batches to cover - migration, modification, set retries

Copy link
Member

@yanavasileva yanavasileva left a comment

Choose a reason for hiding this comment

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

As discussed above, the pull request needs more work.

@punitdarira
Copy link
Contributor Author

JobDeclaration.java

Hi Yana,
The property was being set as null as the value was being fetched from ACT_RU_JOBDEF and right now we are not setting the processdefinitionid in this table. I've added the code to get the value from batch configuration. I've added a new test case but the setup of test case is similar to RestartProcessInstanceAsyncTest.shouldSetExecutionStartTimeInBatchAndHistory so to avoid running the same setup twice, we can maybe just add a new assert statement to the above mentioned method with a comment.

Copy link
Member

@yanavasileva yanavasileva left a comment

Choose a reason for hiding this comment

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

The proposed changes cause failures in other batch tests. Also, I would expect the have tests for all batches for which this change make sense.

we can maybe just add a new assert statement to the above mentioned method with a comment

Yes, you can consider doing that where it make sense add comments (and/or adjust test name) so people are not lost what is tested.

Comment on lines +1177 to +1178
assertEquals(processInstance.getProcessDefinitionId(), jobLog.getProcessDefinitionId());
assertEquals(processInstance.getRootProcessInstanceId(), jobLog.getProcessInstanceId());
Copy link
Member

Choose a reason for hiding this comment

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

❌ The checks are performed for the historic job log, I would expect to check the jobs as well.

@punitdarira
Copy link
Contributor Author

Hi @yanavasileva,
I could think of 3 solutions here.

  1. To make sure every applicable batch type adds the process definition id in ACT_RU_JOBDEF. So that by default it gets picked up via
    job.setProcessDefinitionId(jobDefinition.getProcessDefinitionId());
  2. Doing the same thing as point 1 but with configuration in ACT_RU_BATCH
  3. In AbstractBatchJobHandler.createJobEntities, looking up process definition id from HistoricProcessInstance table using instance id and setting it in the JobEntity.

3rd solution would be the least invasive and clearer. Can you please advice?

@github-actions github-actions bot added group:stale DRI: Yana and removed group:stale DRI: Yana labels Jun 21, 2024
@yanavasileva
Copy link
Member

yanavasileva commented Jun 26, 2024

@punitdarira, I am not sure either of the options is great when we think about performance.
For example, at first glance option 3 (fetching the process definition id via the process instance) sounds good, but that implementation would mean for each batch execution job to have an additional query to the database. At the moment, I don't think it will be worth it. I might overlooked that aspect during the creation of the ticket. I will sync with the team then update you and the ticket with the outcome.

@punitdarira
Copy link
Contributor Author

@punitdarira, I am not sure either of the options is great when we think about performance. For example, at first glance option 3 (fetching the process definition id via the process instance) sounds good, but that implementation would mean for each batch execution job to have an additional query to the database. At the moment, I don't think it will be worth it. I might overlooked that aspect during the creation of the ticket. I will sync with the team then update you and the ticket with the outcome.

sounds good

@yanavasileva
Copy link
Member

@punitdarira, I checked with the team, we want to keep it simple for now and only populate the processDefinitionId field for restart batch operations.
Decision: #4205 (comment).

Copy link
Member

@yanavasileva yanavasileva left a comment

Choose a reason for hiding this comment

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

Added adjustment for the processDefinitionId field.

@github-actions github-actions bot added the group:stale DRI: Yana label Jun 29, 2024
@yanavasileva
Copy link
Member

@punitdarira, are you willing to add further test coverage that the process instance id is populated for other/all type of batch operations?

Comment on lines 34 to 36
import org.camunda.bpm.engine.impl.util.JsonUtil;

import static org.camunda.bpm.engine.impl.RestartProcessInstancesBatchConfigurationJsonConverter.PROCESS_DEFINITION_ID;
Copy link
Member

Choose a reason for hiding this comment

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

❌ Not needed anymore:

Suggested change
import org.camunda.bpm.engine.impl.util.JsonUtil;
import static org.camunda.bpm.engine.impl.RestartProcessInstancesBatchConfigurationJsonConverter.PROCESS_DEFINITION_ID;

@punitdarira
Copy link
Contributor Author

@punitdarira, are you willing to add further test coverage that the process instance id is populated for other/all type of batch operations?

@yanavasileva
Sure Yana

@punitdarira
Copy link
Contributor Author

@yanavasileva ,
Added tests for below batches-
BatchSetVariables
DecisionSetRemovalTime
DeleteHistoricDecisionInstances
DeleteHistoricProcessInstances
DeleteProcessInstancesJob
MessageCorrelationBatchJob
MigrationBatchJob
ModificationBatchJob
ProcessSetRemovalTimeJob
RestartProcessInstanceBatchJob
UpdateProcessInstancesSuspendStateJob

However, there were 3 batch types which were operating on batches directly like-
BatchSetRemovalTime
SetExternalTaskRetriesJob
SetJobRetriesJob

For these jobs, the processInstanceId is not being set as expected. I can see the job's id being set instead of the processInstaceId. Just to confirm, the execution jobs for these 3 batches should have the process instacancesId of the transitive instance right?

@yanavasileva
Copy link
Member

Thanks for adding the tests. 💯

For these jobs, the processInstanceId is not being set as expected. I can see the job's id being set instead of the processInstaceId. Just to confirm, the execution jobs for these 3 batches should have the process instacancesId of the transitive instance right?

I will check and get back to you. The first one, we won't need a process instance id but I am not sure for the others.

yanavasileva pushed a commit that referenced this pull request Sep 5, 2024
Copy link
Member

@yanavasileva yanavasileva left a comment

Choose a reason for hiding this comment

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

I am not ready with the review. However, I am sharing my comments to prevent losing them.
Some adjustments needs to be done for suspend and migration batches, I will look at that.

Comment on lines +151 to +163
@Test
public void shouldCreateProcessInstanceRelatedBatchJobsForSingleInvocations(){
// when
Batch batch = historyService.deleteHistoricDecisionInstancesAsync(decisionInstanceIds, null);
helper.executeSeedJob(batch);

//then
//Making sure that processInstanceId is set in execution jobs #4205
assertThat(helper.getExecutionJobs(batch))
.extracting("processInstanceId")
.containsExactlyInAnyOrder(decisionInstanceIds.toArray());
}

Copy link
Member

Choose a reason for hiding this comment

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

❌ The processInstanceId should not be populated for this type of a batch. It is incorrect to store the decision ids as process instance ids.

Suggested change
@Test
public void shouldCreateProcessInstanceRelatedBatchJobsForSingleInvocations(){
// when
Batch batch = historyService.deleteHistoricDecisionInstancesAsync(decisionInstanceIds, null);
helper.executeSeedJob(batch);
//then
//Making sure that processInstanceId is set in execution jobs #4205
assertThat(helper.getExecutionJobs(batch))
.extracting("processInstanceId")
.containsExactlyInAnyOrder(decisionInstanceIds.toArray());
}

@@ -109,6 +111,21 @@ public void testDeleteHistoryProcessInstancesAsyncWithList() throws Exception {
assertAllHistoricProcessInstancesAreDeleted();
}

@Test
public void testDeleteHistoryProcessInstances_shouldCreateProcessInstanceRelatedBatchJobsForSingleInvocations() {
Copy link
Member

Choose a reason for hiding this comment

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

🔧 Better

Suggested change
public void testDeleteHistoryProcessInstances_shouldCreateProcessInstanceRelatedBatchJobsForSingleInvocations() {
public void shouldPopulateProcessInstanceIdToBatchJobsForSingleInvocations() {

Comment on lines +2885 to +2889

//Making sure that processInstanceId is set in execution jobs #4205
assertThat(executionJobs)
.extracting("processInstanceId")
.containsExactlyInAnyOrder(query.list().stream().map(HistoricDecisionInstance::getId).toArray());
Copy link
Member

Choose a reason for hiding this comment

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

❌ Process instance id should not be populated for decision related batches:

Suggested change
//Making sure that processInstanceId is set in execution jobs #4205
assertThat(executionJobs)
.extracting("processInstanceId")
.containsExactlyInAnyOrder(query.list().stream().map(HistoricDecisionInstance::getId).toArray());

Comment on lines +2866 to +2868

HistoricDecisionInstanceQuery query = historyService.createHistoricDecisionInstanceQuery();

Copy link
Member

Choose a reason for hiding this comment

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

❌ Not needed:

Suggested change
HistoricDecisionInstanceQuery query = historyService.createHistoricDecisionInstanceQuery();

Copy link
Member

Choose a reason for hiding this comment

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

❌ ✍️ Please check test #createModificationJobs() is failing. processInstanceId assertions must be adjusted.

Comment on lines +115 to +116


Copy link
Member

Choose a reason for hiding this comment

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

Suggested change

Copy link
Member

Choose a reason for hiding this comment

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

Note to myself:
❓ Tests failures due to Entity was updated by another transaction concurrently. What's wrong

Copy link
Member

Choose a reason for hiding this comment

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

See: org.camunda.bpm.engine.impl.persistence.entity.JobManager.updateJobSuspensionStateByProcessInstanceId(String, SuspensionState)

Copy link
Member

Choose a reason for hiding this comment

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

Note to myself:
Tests failures due to

java.lang.NullPointerException: null
	at org.camunda.bpm.engine.impl.persistence.entity.JobEntity.setExecution(JobEntity.java:259)
	at org.camunda.bpm.engine.impl.persistence.entity.ExecutionEntity.restoreProcessInstance(ExecutionEntity.java:1384)

See org.camunda.bpm.engine.impl.migration.instance.parser.MigratingInstanceParser.fetchJobs(CommandContext, String)

@@ -169,6 +169,11 @@ protected void createJobEntities(BatchEntity batch, T configuration, String depl
ByteArrayEntity configurationEntity = saveConfiguration(byteArrayManager, jobConfiguration);

JobEntity job = createBatchJob(batch, configurationEntity);

if (jobConfiguration.getIds() != null && jobConfiguration.getIds().size() == 1) {
Copy link
Member

Choose a reason for hiding this comment

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

Something like this will be required to avoid populating the ids for entities that are not process instance:

Suggested change
if (jobConfiguration.getIds() != null && jobConfiguration.getIds().size() == 1) {
if (jobConfiguration.getIds() != null && jobConfiguration.getIds().size() == 1
&& !(this instanceof DecisionSetRemovalTimeJobHandler)
&& !(this instanceof DeleteHistoricDecisionInstancesJobHandler)
&& !(this instanceof SetJobRetriesJobHandler)
&& !(this instanceof SetExternalTaskRetriesJobHandler)
// && !(this instanceof BatchSetRemovalTimeJobHandler)
) {

@yanavasileva
Copy link
Member

Just dropping by to say that I didn't have the chance to work on this.
We already started with the other tasks related to this topic so I will provide feedback in the next weeks.

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.

2 participants