-
Hi, To which extend is it advisable to call an activity in a while loop? In the case I guessed it right, what is the right way to periodically check a long running operation on a third party service? |
Beta Was this translation helpful? Give feedback.
Replies: 7 comments 3 replies
-
If you invoke For example: for ($i=0; $i < 2; $i++) {
yield ActivityStub::make(SimpleActivity::class);
} This is equivalent to: yield ActivityStub::make(SimpleActivity::class);
yield ActivityStub::make(SimpleActivity::class); In both instances, the activity will be executed twice. It's only when a workflow crashes and is reloaded that the same result might be fetched from the logs to avoid redundant operations. So, your activity will indeed run each time you call it in your loop. |
Beta Was this translation helpful? Give feedback.
-
Thanks for the answer. That's the code in my workflow while($this->isStartable($this->status))
{
$this->status = yield ActivityStub::make(MakeActivity::class);
while($this->isPending($this->status))
{
yield WorkflowStub::timer($this->checkInterval);
$this->status = yield ActivityStub::make(CheckActivity::class);
}
yield WorkflowStub::await(fn() => $this->restarted && !$this->isWaiting($this->status));
}
return $this->status; And this is the signal method. /**
* @var bool
*/
private bool $restarted = false;
/**
* @return void
*/
#[SignalMethod]
public function restart()
{
$this->restarted = true;
} I had to upgrade the app and restart the Laravel worker while the workflow was in waiting status, and after that, it kept returning to the waiting status after receiving the signal. My next question is how to ensure that the |
Beta Was this translation helpful? Give feedback.
-
Do we need to have an option to bypass the logs for a specific call or for an activity? |
Beta Was this translation helpful? Give feedback.
-
What about adding the above method to the public static function force($activity, ...$arguments): PromiseInterface
{
// Same as make(), but without fetching the previous result from the logs.
$context = WorkflowStub::getContext();
$activity::dispatch($context->index, $context->now, $context->storedWorkflow, ...$arguments);
++$context->index;
WorkflowStub::setContext($context);
$deferred = new Deferred();
return $deferred->promise();
} It's name may not be the best, so anyone can suggest another. |
Beta Was this translation helpful? Give feedback.
-
I am not sure I understand why you would want to do that? |
Beta Was this translation helpful? Give feedback.
-
It sounds like you are not using signals to their full potential. An activity should not be run in a loop to check status. You should send the status to the workflow. |
Beta Was this translation helpful? Give feedback.
-
Hi, Finally I've decided to revert to a single call which throws an exception while the operation is pending, instead of a loop. |
Beta Was this translation helpful? Give feedback.
If you invoke
ActivityStub::make()
multiple times within a loop, it doesn't just return the same result as the first call. Instead, it will initiate and execute the activity for each call.For example:
This is equivalent to:
In both instances, the activity will be executed twice. It's only when a workflow crashes and is reloaded that the same result might be fetched from the logs to avoid redundant operations. So, your activity will indeed run each time you call it in your loop.