An easy way that you can do is draw a new route from the initiator to the end of the process (Complete) and label it as "Cancel Request" which will appear on the workspace as a new button (besides the Complete/Submit button) so the assigneed can either click on "Cancel Request" or "Submit" to continue the process. You can do the same for each of the assignee. Hope it helps!
You can create a workflow process using gateways. Gateways allow multiple logic paths.
Split the w/f after the initial step. One leg is your current approval process, the other leg of the gateway routes to a user task assigned to the initiator ( they get a to-do that will allow them to cancel).
Set the gateway to be an 'Or' type instead of an 'And' - so that if either leg completes, the workflow is done.
I have not done this in a while, so you will need to experiment to see if it cleans up all the tasks from the participants.
I had to build a dynamic w/f with over 100 possible participants and had to create a custom component to clean up the subordinate user tasks.
Hope this helps.
Thanks Mark! Also thank you to WASIL and Han Dao for taking the time to offer suggestions. Mark, you have it on the nose. My concern was that after the initiator had submitted the request, they really had no way of taking any action. I will obviously, as you said, figure out how to clean up tasks. I may create a custom component to do that as you suggested. This is awesome, thanks!
Here is what you can do:
Modify your process slightly, so that the person invoking the process would get a notification which contains "processInstanceID".
You can then create a simple XFA based PDF which could call the below webService:
the operation you need to call is "terminateProcess", which takes the above mentioned "ProcessInstanceID" as input and would terminate the specified instance for you.
If you can trigger a notification in form of assignTask, then you can use the above mentioned PDF as input template for the same. which means every initiator has the option to terminate any invoked process instance and that too by submitting a task in the workspace as and when required.
Let me know if this helps.