Skip to content
Merged
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
50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,56 @@ composer require cbws/php-cbws

## Usage

### Long-running operations

Many interactions with the CBWS cloud platform will be long-running operations that run on the background, these can
be polled until the operation has finished. After which the response or error will be available.

### Getting the current operation status

Operations have a `get()` method that fetches the current state of the operation.

```php
<?php
$operation = $machine->stop();

// Get the latest status of the operation
$operation = $operation->get();

var_dump($operation->getDone());
var_dump($operation->getResponse());
if ($operation->getError() !== null) {
throw $operation->getError();
}
```

### Async/await with PHP fibers

With the built-in PHP fibers it is possible to wait until the operation has finished, either successfully or with an error:

```php
$operation = $machine->stop();

// Get the fiber that will wait until the operation has finished.
$fiber = $operation->fiber();
$fiber->start();

while (!$fiber->isTerminated()) {
// Get intermediate operation state
$operation = $fiber->resume();
}

// Finished operation
$operation = $fiber->getReturn();

var_dump($operation->getDone());
var_dump($operation->getResponse());
if ($operation->getError() !== null) {
throw $operation->getError();
}

```

### Compute

```php
Expand Down
11 changes: 11 additions & 0 deletions src/Common/Longrunning/Model/Operation.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
use Cbws\Sdk\Common\Longrunning\Operations;
use Cbws\Sdk\Common\Longrunning\ResponseInterface;
use Exception;
use Fiber;

/**
* @template TMetadata of MetadataInterface
Expand Down Expand Up @@ -86,6 +87,16 @@ public function await(): self
return $this->client->awaitOperation($this->getName(), $this->metadataType, $this->responseType);
}

/**
* Provider Fiber for waiting until the operation has finished, either successfully or with an error.
*
* @return Fiber<?int, ?int, Operation<TMetadata, TResponse>, Operation<TMetadata, TResponse>>
*/
public function fiber(): Fiber
{
return $this->client->fiberOperation($this->getName(), $this->metadataType, $this->responseType);
}

public function __debugInfo()
{
return [
Expand Down
35 changes: 35 additions & 0 deletions src/Common/Longrunning/Operations.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
use Cbws\Sdk\Common\Longrunning\V1alpha1\DeleteOperationRequest;
use Cbws\Sdk\Common\Longrunning\V1alpha1\GetOperationRequest;
use Cbws\Sdk\Common\Longrunning\V1alpha1\WaitOperationRequest;
use Fiber;
use Generator;
use Google\Protobuf\GPBEmpty;

Expand Down Expand Up @@ -181,4 +182,38 @@ public function awaitOperation(string $name, string $metadataType, string $respo
/** @phpstan-var Operation<TMetadata, TResponse> */
return $operation;
}

/**
* Provider Fiber for waiting until the operation has finished, either successfully or with an error.
*
* @template TMetadata of MetadataInterface
* @template TResponse of ResponseInterface
*
* @param class-string<TMetadata> $metadataType
* @param class-string<TResponse> $responseType
*
* @return Fiber<?int, ?int, Operation<TMetadata, TResponse>, Operation<TMetadata, TResponse>>
*/
public function fiberOperation(string $name, string $metadataType, string $responseType): Fiber
{
/** @phpstan-var Fiber<?int, ?int, Operation<TMetadata, TResponse>, Operation<TMetadata, TResponse>> */
return new Fiber(function (?int $timeout = 5) use ($name, $metadataType, $responseType) {
do {
$operation = $this->waitOperation($name, $metadataType, $responseType, $timeout ?: 5);

// We should see if we can have a way of providing a non-blocking way to implement fibers, doing get over
// and over again would put a massive load on our service.
// if ($timeout !== null) {
// $operation = $this->waitOperation($name, $metadataType, $responseType, $timeout);
// } else {
// $operation = $this->getOperation($name, $metadataType, $responseType);
// }

/** @phpstan-var ?int $timeout */
$timeout = Fiber::suspend($operation);
} while (!$operation->getDone());

return $operation;
});
}
}
20 changes: 20 additions & 0 deletions tests/Integration/Compute/MachinesTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,26 @@ public function test_start_machine(): void
self::assertTrue($operation->getDone());
}

public function test_start_machine_fiber(): void
{
assert($this->client !== null);
$machine = $this->client->machines()->get('php-cbws-test1');
$fiber = $machine->start()->fiber();
$fiber->start();

// Wait until operation has finished
while (!$fiber->isTerminated()) {
$fiber->resume();
}

$operation = $fiber->getReturn();

if ($operation->getError() !== null) {
throw $operation->getError();
}
self::assertTrue($operation->getDone());
}

// public function test_update_instance(): void
// {
// $operation = $this->client->updateInstance('php-cbws-test1', Instance::create()->withCPU(2));
Expand Down
Loading