Skip to content

Async Operations

All API methods support async execution via async(), returning GuzzleHttp\Promise\PromiseInterface instead of blocking until the response arrives. Existing sync behaviour is unchanged.

Builder Async

Call async() on a builder to switch all subsequent operations to async mode:

php
use Rollogi\LaravelHubspot\Crm\Contact;

// Create asynchronously
$promise = Contact::query()->async()->create([
    'firstname' => 'Jane',
    'email' => 'jane@example.com',
]);

$result = $promise->wait(); // array of created contact data

// Find asynchronously
$promise = Contact::query()->async()->find('123');
$contact = $promise->wait(); // Contact|null

// Delete asynchronously
$promise = Contact::query()->async()->delete();
$promise->wait(); // true

// Batch operations run chunks concurrently in async mode
$promise = Contact::query()->async()->createMany([
    ['firstname' => 'One'],
    ['firstname' => 'Two'],
]);
$results = $promise->wait(); // array of created records

You can reset the flag with async(false):

php
$builder = Contact::query()->async();
$builder->async(false); // back to sync mode

Model Async

Use $model->async() to get an async proxy that fires before-events synchronously and after-events in the promise chain:

php
// Create
$contact = new Contact(['firstname' => 'Jane', 'email' => 'jane@example.com']);
$promise = $contact->async()->save();
$contact = $promise->wait(); // hydrated Contact with exists = true

// Update
$contact->firstname = 'Updated';
$promise = $contact->async()->save();
$contact = $promise->wait();

// Delete
$promise = $contact->async()->delete();
$deleted = $promise->wait(); // true

// Cancelled events return a resolved promise with the unchanged model
Event::listen(Saving::class, fn () => false);
$promise = $contact->async()->save();
$result = $promise->wait(); // unchanged model, no HTTP request sent

Pool

Execute multiple operations concurrently with HubSpot::pool():

php
use Rollogi\LaravelHubspot\Crm\Contact;
use Rollogi\LaravelHubspot\Crm\Company;
use Rollogi\LaravelHubspot\Facades\HubSpot;

$results = HubSpot::pool()
    ->add(Contact::class, 'create', [['firstname' => 'Jane', 'email' => 'jane@example.com']])
    ->add(Contact::class, 'create', [['firstname' => 'John', 'email' => 'john@example.com']])
    ->add(Company::class, 'create', [['name' => 'Acme Corp']])
    ->send();

// $results is an array of resolved values or Throwable instances
foreach ($results as $result) {
    if ($result instanceof \Throwable) {
        // Handle error
    }
}

Configure default concurrency via config or pass it directly:

php
// config/hubspot.php
'async' => [
    'default_concurrency' => 5,
],

// Or pass directly
HubSpot::pool(concurrency: 10)->add(...)->send();

Promise Chaining

All async methods return standard GuzzleHttp\Promise\PromiseInterface:

php
$promise = Contact::query()->async()->find('123');

$promise
    ->then(fn (?Contact $contact) => $contact?->firstname)
    ->then(fn (?string $name) => logger()->info('Found: ' . $name));

$promise->wait(); // resolve the chain