Commit 5effdc8f authored by Yusei Tahara's avatar Yusei Tahara

SolverProcess may not be 'solved' when there are several 'solve()' Activities...

SolverProcess may not be 'solved' when there are several 'solve()' Activities executed in parallel (#KMS-1126).

  1. Two POLs diverge.
     => Solver Process is created ('draft').
  2. User 'Accept Decision' (Accept Solver) on all of them:
     1) Two Accept Solvers are created in the Solver Process, one per divergence.
     2) SolverProcess.solve() is called, on each Accept Solver:
        1/ AcceptSolver.startSolving() ()
           => Through solver_workflow 'Script (after)': SolverProcess.startSolving()
              => Solver Process is in 'solving' state.
        2/ AcceptSolver.activate().solve()
           => One solve() Activity per Accept Solver.
              => AcceptSolver.succeed()
                 => Through solver_workflow 'Script (after)': SolverProcess.succeed()

The last step, 'SolverProcess.succeed()', will only be executed if and only if
all the other Accept Solver of the Solver Process are in 'solved' state. However,
if both Activities are executed in parallel, each Activity does not see the result
of the other, and thus the other Accept Solver is still in 'solving' state. At
the end the Solver Process may stay in 'solving' state.

Thus try to update solver process workflow state after target solver finished its job
by activity. Also try to update solver process workflow state when a new divergence occurs
and if solver process is still in solving state.
parent 072d7d55
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="PythonScript" module="Products.PythonScripts.PythonScript"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>Script_magic</string> </key>
<value> <int>3</int> </value>
</item>
<item>
<key> <string>_bind_names</string> </key>
<value>
<object>
<klass>
<global name="NameAssignments" module="Shared.DC.Scripts.Bindings"/>
</klass>
<tuple/>
<state>
<dictionary>
<item>
<key> <string>_asgns</string> </key>
<value>
<dictionary>
<item>
<key> <string>name_container</string> </key>
<value> <string>container</string> </value>
</item>
<item>
<key> <string>name_context</string> </key>
<value> <string>context</string> </value>
</item>
<item>
<key> <string>name_m_self</string> </key>
<value> <string>script</string> </value>
</item>
<item>
<key> <string>name_subpath</string> </key>
<value> <string>traverse_subpath</string> </value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</state>
</object>
</value>
</item>
<item>
<key> <string>_body</string> </key>
<value> <string>if context.getPortalType() != \'Solver Process\':\n
return\n
\n
if context.getValidationState() != \'solving\':\n
return\n
\n
# Maybe all target solvers have already been solved.\n
# Check their state and if all of them were solved,\n
# then update the state of solver process\n
for target_solver in context.objectValues(\n
portal_type=context.getPortalObject().getPortalTargetSolverTypeList()):\n
if target_solver.getValidationState() != \'solved\':\n
# Currently solving Divergences through solve() Activity\n
return False\n
\n
# All target solvers were solved.\n
context.succeed()\n
\n
return True\n
</string> </value>
</item>
<item>
<key> <string>_params</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>_proxy_roles</string> </key>
<value>
<tuple>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>SolverProcess_updateWorkflowState</string> </value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -55,8 +55,9 @@ draft_solver_process = None\n
for solver_process in delivery.getSolverValueList():\n
validation_state = solver_process.getValidationState()\n
if validation_state == \'solving\':\n
# Currently solving Divergences through solve() Activity\n
return\n
if not solver_process.SolverProcess_updateWorkflowState():\n
# Currently solving Divergences through solve() Activity\n
return\n
elif solver_process.getValidationState() == \'draft\':\n
draft_solver_process = solver_process\n
\n
......
......@@ -54,6 +54,8 @@
for solver in solver_process.objectValues(\n
portal_type=solver_process.getPortalObject().getPortalTargetSolverTypeList()):\n
if solver.getValidationState() != \'solved\':\n
# Try to update solver process workflow state to avoid race condition.\n
solver_process.activate(activity=\'SQLQueue\').SolverProcess_updateWorkflowState()\n
return\n
solver_process.succeed()\n
</string> </value>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment