google/longrunning
Idiomatic PHP client for Google’s LongRunning Operations API. Install via Composer, supports REST and optional gRPC for streaming, and integrates with Google Cloud PHP authentication and debugging guides. Beta but largely stable.
Installation:
composer require google/longrunning
For gRPC support (recommended for high-throughput scenarios):
pecl install grpc
composer require google/longrunning-grpc
Authentication:
Configure a service account with the required GCP permissions (e.g., roles/cloud-platform.viewer for read-only operations). Use the google/auth package for authentication:
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Cloud\LongRunning\LongRunningClient;
$credentials = ServiceAccountCredentials::fromStream('path/to/service-account.json');
$client = new LongRunningClient(['credentials' => $credentials]);
First Use Case: Poll a long-running operation (e.g., from a Laravel job):
use Google\Cloud\LongRunning\LongRunningClient;
use Google\Cloud\LongRunning\Operation;
$client = app(LongRunningClient::class); // Inject via Laravel service provider
$operationName = 'projects/my-project/locations/my-location/operations/my-operation-id';
$operation = $client->getOperation($operationName);
// Poll until completion
$result = $operation->pollUntilDone();
$metadata = $result->getMetadata();
$response = $result->getResponse();
// app/Providers/GoogleLongRunningServiceProvider.php
public function register()
{
$this->app->singleton(LongRunningClient::class, function ($app) {
$credentials = ServiceAccountCredentials::fromStream(config('services.google.credentials_path'));
return new LongRunningClient(['credentials' => $credentials]);
});
}
Use the pollUntilDone() method in a queued job to wait for GCP operation completion:
// app/Jobs/ProcessGcpOperation.php
public function handle(LongRunningClient $client)
{
$operationName = 'projects/my-project/locations/my-location/operations/' . $this->operationId;
$operation = $client->getOperation($operationName);
// Poll with exponential backoff (customize as needed)
$result = $operation->pollUntilDone([
'timeout' => 3600, // 1 hour timeout
'retryDelay' => 5, // Initial delay in seconds
'maxRetryDelay' => 60, // Max delay in seconds
]);
// Process the result
$this->processResult($result->getResponse());
}
Cancel a long-running operation (e.g., user-triggered cancellation):
public function cancelOperation(LongRunningClient $client, string $operationName)
{
$client->cancelOperation($operationName);
// Optionally notify the user via Laravel Notifications
}
Fetch a list of operations (e.g., for admin dashboards):
public function listOperations(LongRunningClient $client, string $parent)
{
$operations = $client->listOperations($parent, [
'filter' => 'state=RUNNING', // Optional filter
'pageSize' => 100,
]);
foreach ($operations as $operation) {
// Render in Blade or process further
}
}
For high-throughput scenarios, use gRPC to stream operation updates:
// Requires gRPC extension and google/longrunning-grpc
$client = new \Google\Cloud\LongRunning\Grpc\LongRunningClient(['credentials' => $credentials]);
$stream = $client->listOperations($parent, ['stream' => true]);
foreach ($stream as $operation) {
// Process each operation as it arrives
}
ProcessGcpOperation::dispatch($operationId)->onQueue('gcp');
pollUntilDone() to wait for the operation to complete.listOperations() to fetch all running operations for a project/location.@foreach($operations as $operation)
<div class="operation-status">
<progress value="{{ $operation->getProgress() }}" max="100"></progress>
<button onclick="cancelOperation('{{ $operation->getName() }}')">Cancel</button>
</div>
@endforeach
Customize polling behavior to optimize API calls and costs:
$operation->pollUntilDone([
'retryDelay' => 2, // Start with 2-second delay
'maxRetryDelay' => 30, // Cap at 30 seconds
'multiplier' => 2, // Exponential backoff multiplier
]);
Centralize client configuration and authentication:
// config/services.php
'google' => [
'credentials_path' => storage_path('app/google-credentials.json'),
'project_id' => 'my-project-id',
];
// app/Providers/AppServiceProvider.php
public function boot()
{
$this->app->singleton(LongRunningClient::class, function ($app) {
$credentials = ServiceAccountCredentials::fromStream(
$app['config']['services.google.credentials_path']
);
return new LongRunningClient([
'credentials' => $credentials,
'scopes' => [Google\Cloud\Core\Grpc\GrpcServiceClient::CLOUD_PLATFORM_SCOPE],
]);
});
}
Extend Laravel Horizon to monitor GCP operations:
// app/Console/Commands/MonitorGcpOperations.php
public function handle()
{
$client = app(LongRunningClient::class);
$operations = $client->listOperations('projects/my-project');
foreach ($operations as $operation) {
Horizon::job(ProcessGcpOperation::class, ['operationId' => $operation->getName()]);
}
}
Create a Blade directive to render operation statuses:
// app/View/Composers/OperationStatusComposer.php
public function compose($view)
{
$view->with('operationStatus', $this->getOperationStatus($operationName));
}
// In Blade:
@operationStatus($operationName)
<div class="status-{{ $status }}">{{ $message }}</div>
@endoperationStatus
Google\Auth\Exception\InvalidCredentialsException when the service account lacks permissions.roles/cloud-platform.viewer for read operations). Verify the credentials file path and JSON content.google/auth package’s debug tools:
$credentials->debug();
Google\Cloud\LongRunning\Exception\NotFoundException when polling a non-existent operation.projects/{project}/locations/{location}/operations/{operation}). Use listOperations() to verify the operation exists before polling.How can I help you explore Laravel packages today?