Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions ProcessMaker/Jobs/BpmnAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Illuminate\Support\Facades\App;
Expand Down Expand Up @@ -76,6 +77,8 @@ public function handle()
if ($this->processId !== 'non_persistent_process') {
HandleRedirectListener::sendRedirectToEvent();
}
} catch (HttpResponseException $exception) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@gproly Why this change is needed?

throw $exception;
} catch (HttpABTestingException $exception) {
Log::error($exception->getMessage());
throw $exception;
Expand Down
16 changes: 16 additions & 0 deletions ProcessMaker/Jobs/CancelRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@

namespace ProcessMaker\Jobs;

use Carbon\Carbon;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Support\Facades\Notification;
use ProcessMaker\Models\ProcessRequest;
use ProcessMaker\Models\ProcessRequestToken;
use ProcessMaker\Nayra\Contracts\Bpmn\ActivityInterface;
use ProcessMaker\Notifications\ProcessCanceledNotification;
use ProcessMaker\Repositories\ExecutionInstanceRepository;
use ProcessMaker\Repositories\TokenRepository;
Expand Down Expand Up @@ -49,5 +52,18 @@ public function action(ProcessRequest $instance)
foreach ($instance->getTokens()->toArray() as $token) {
$tokenRepo->store($token);
}

// Close tokens that were created after the in-memory snapshot (race with parallel
// gateways / concurrent completions).
ProcessRequestToken::query()
->where('process_request_id', $instance->getKey())
->where('status', '!=', ActivityInterface::TOKEN_STATE_CLOSED)
->update([
'status' => ActivityInterface::TOKEN_STATE_CLOSED,
'completed_at' => Carbon::now(),
'due_at' => null,
'riskchanges_at' => null,
'user_id' => null,
]);
}
}
20 changes: 19 additions & 1 deletion ProcessMaker/Jobs/RunNayraScriptTask.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use ProcessMaker\Exception\ScriptException;
use ProcessMaker\Facades\WorkflowManager;
use ProcessMaker\Managers\DataManager;
use ProcessMaker\Models\ProcessRequest;
use ProcessMaker\Models\ProcessRequestToken;
use ProcessMaker\Models\Script;
use ProcessMaker\Models\ScriptExecutor;
Expand All @@ -36,7 +37,7 @@ class RunNayraScriptTask implements ShouldQueue
/**
* Create a new job instance.
*
* @param \ProcessMaker\Models\ProcessRequestToken $token
* @param ProcessRequestToken $token
* @param array $data
*/
public function __construct(TokenInterface $token)
Expand Down Expand Up @@ -99,10 +100,27 @@ public function handle()

$response = $script->runScript($data, $configuration, $token->getId(), $errorHandling->timeout());

if (ProcessRequest::query()->whereKey($instance->getKey())->value('status') === 'CANCELED') {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@gproly Not sure if this is needed, because completeTask verifies that the token is ACTIVE. Could you try to remove this code?

Log::info('Skipping script task completion because the request was canceled.', [
'process_request_id' => $instance->getKey(),
'token_id' => $token->getKey(),
]);

return;
}

// Dispatch complete task action
WorkflowManager::completeTask($processModel, $instance, $token, $response['output']);
} catch (ConfigurationException $exception) {
$output = $exception->getMessageForData($token);
if (ProcessRequest::query()->whereKey($instance->getKey())->value('status') === 'CANCELED') {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@gproly Not sure if this is needed, because completeTask verifies that the token is ACTIVE. Could you try to remove this code?

Log::info('Skipping script task completion because the request was canceled.', [
'process_request_id' => $instance->getKey(),
'token_id' => $token->getKey(),
]);

return;
}
WorkflowManager::completeTask($processModel, $instance, $token, $output);
} catch (Throwable $exception) {
Log::error('Script failed: ' . $scriptRef . ' - ' . $exception->getMessage());
Expand Down
9 changes: 9 additions & 0 deletions ProcessMaker/Nayra/Managers/WorkflowManagerDefault.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace ProcessMaker\Nayra\Managers;

use Illuminate\Http\Exceptions\HttpResponseException;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Validator;
Expand Down Expand Up @@ -71,6 +72,14 @@ public function completeTask(Definitions $definitions, ExecutionInstanceInterfac
//Validate data
$element = $token->getDefinition(true);
$this->validateData($data, $definitions, $element);
if ($instance instanceof ProcessRequest) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

@gproly Not sure if this is needed, because CompleteActivity should verify that the token is ACTIVE. Could you check if this verification could go to the Job?

$status = ProcessRequest::query()->whereKey($instance->getKey())->value('status');
if ($status === 'CANCELED') {
throw new HttpResponseException(response()->json([
'message' => __('This request has been canceled. The task cannot be completed.'),
], 422));
}
}
CompleteActivity::dispatchSync($definitions, $instance, $token, $data);
}

Expand Down
5 changes: 5 additions & 0 deletions ProcessMaker/Repositories/ExecutionInstanceRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,11 @@ public function persistInstanceCompleted(ExecutionInstanceInterface $instance)
return;
}

$currentStatus = ProcessRequest::query()->whereKey($instance->getKey())->value('status');
if ($currentStatus === 'CANCELED') {
return;
}

// Save completed instance
$instance->status = 'COMPLETED';
$instance->completed_at = Carbon::now();
Expand Down
21 changes: 21 additions & 0 deletions ProcessMaker/Repositories/TokenRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,27 @@ public function persistActivityActivated(ActivityInterface $activity, TokenInter
if ($process->isNonPersistent()) {
return;
}
$instance = $token->getInstance();
if ($instance instanceof ProcessRequest) {
$currentStatus = ProcessRequest::query()->whereKey($instance->getKey())->value('status');
if ($currentStatus === 'CANCELED') {
$token->status = ActivityInterface::TOKEN_STATE_CLOSED;
$token->element_id = $activity->getId();
$token->element_type = $this->getActivityType($activity);
$token->element_name = $activity->getName();
$token->process_id = $instance->process_id;
$token->process_request_id = $instance->getKey();
$token->user_id = null;
$token->due_at = null;
$token->riskchanges_at = null;
$token->completed_at = Carbon::now();
$token->updateTokenProperties();
$token->saveOrFail();
$token->setId($token->getKey());

return;
}
}
$token->status = ActivityInterface::TOKEN_STATE_ACTIVE;
$token->element_id = $activity->getId();
$token->element_type = $this->getActivityType($activity);
Expand Down
Loading