Skip to content

How to setup execution timeout for synchronous tasks with blocking IO? #209

@3DFace

Description

@3DFace

Hello!

It seems like ContextWorker relies on task-runner process/thread to react on cancellation.
But in a case of blocking IO task-runner can't do that.

<?php
use Amp\Cancellation;
use Amp\Parallel\Worker\Task;
use Amp\Sync\Channel;
use Amp\TimeoutCancellation;
use function Amp\Parallel\Worker\submit;

class SleepTask implements Task
{
    public function __construct(private int $seconds) {}
	
    public function run(Channel $channel, Cancellation $cancellation) : int
    {
        \sleep($this->seconds); // to emulate blocking IO
        return $this->seconds;
    }
}

public function test() : int
{
    $exec_timeout = new TimeoutCancellation(2);
    $task = new SleepTask(10);
    return submit($task, $exec_timeout)->await();
}

echo test().PHP_EOL;

I want to make SleepTask get failed after 2 seconds. But it runs 10 seconds instead.

If I replace in ContextWorker this:

$cancellation->subscribe(static fn () => async(
    $context->send(...),
    new Internal\JobCancellation($jobId),
)->ignore());

with:

$cancellation->subscribe(fn () => async(
    $this->kill(...)
)->ignore());

it works as I want.

Is there any correct way to achieve such behavior (kill on timeout)?

Probably having $context reference in Amp\Parallel\Worker\Execution would be helpful.
It would be possible to call $context->kill() from user-space code.

Thanks in advance.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions