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

add foreach.RunParallel option #597

Merged
merged 2 commits into from
Aug 2, 2020

Conversation

dviry
Copy link
Contributor

@dviry dviry commented Jul 10, 2020

I've seen multiple questions about the ForEach parallel execution and in my use case the TData object defines whether it should run in parallel or synchronous (think a chain of emails for approvals), so I've played around Decide and ForEach vs While but I found it much easier to simply extend the existing ForEach Primitive with a .RunParallel boolean (by default set to True to keep it backward compatible). I think it's a nice addition to this otherwise great library and maybe beneficial to others as well.

I've added the Mongo serialization (only one tested since that's what I use - could not get the other DB Provider tests to run), a new Sample and a link in the readme.

I hope this satisfies your PR requirements and I do hope to see this soon released (obviously I am open to any feedback!)

Thanks in advance

Copy link
Owner

@danielgerlag danielgerlag left a comment

Choose a reason for hiding this comment

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

Awesome contribution! Thank you!

}

if (context.PersistenceData is ControlPersistenceData)
if (context.PersistenceData is IteratorPersistenceData persistanceData && persistanceData?.ChildrenActive == true)
Copy link
Owner

Choose a reason for hiding this comment

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

We need to remain backwards compatible... there may be live workflows out there with ForEach steps that have ControlPersistenceData persisted against them, so we still need to support that.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

you are right! I'll check instead for ControlPersistenceData and only for IteratorPersistenceData if .RunParallel is set to False

Copy link
Owner

Choose a reason for hiding this comment

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

You could also test what the type is, then we simplify by not maintaining 2 persistence types moving forward.

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 hope my latest push matches what you had in mind... I did not want to overcomplicate the code so I kept the two separated.

@@ -306,6 +306,25 @@ private WorkflowStep IterateParents(int id, string name)
return stepBuilder;
}

public IContainerStepBuilder<TData, Foreach, Foreach> ForEach(Expression<Func<TData, IEnumerable>> collection, Expression<Func<TData, bool>> runParallel)
Copy link
Owner

Choose a reason for hiding this comment

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

I wonder if we should add runParallel as an optional parameter to the existing methods? Thoughts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

of course that would be a nice global feature but I am not sure how would work in a .While (that does not actually pass any Context.Item) - that would require more refactoring and could be done in a separate PR.
Also I was thinking of somehow passing the .Index property (like in a for loop instead a foreach) - sometimes might be useful to know which item index is actually being processed (i.e. first, last, somewhere in between...); but that would require a separate .Context.ItemOrder property which I did not want to add to the base class.

WaitForWorkflowToComplete(workflowId, TimeSpan.FromSeconds(30));

GetStatus(workflowId).Should().Be(WorkflowStatus.Complete);
GetData(workflowId).Counter.Should().Be(3);
Copy link
Owner

Choose a reason for hiding this comment

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

Can we assert that it was sync?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

only way I could find to test it is with the Sleep and Counter - the test will fail is .runParallel is set to True. Do you have any better ideas how to actually Assert that?

@danielgerlag danielgerlag merged commit 15862c2 into danielgerlag:master Aug 2, 2020
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