AlexaCRM/dynamics-webapi-toolkit

Speed up calls - 10,8 TTFB

adrian-schnell opened this issue · 2 comments

I'm using to make a couple of simultaneous calls via the AlexaCRM using RetrieveMultiple-FetchExpression calls.

The problem is, that the calls are really slow.. I realized TTFB times up to 11,8 sec.
Screenshot 2020-01-21 08 03 11

I initialize the client with the code from the docu:

private function __construct()
    {
        try {
            $clientFactory = ClientFactory::createOnlineClient(
                env('CRM_INSTANCE_URL', null),
                env('CRM_APPLICATION_ID', null),
                env('CRM_APPLICATION_SECRET', null)
            );
            $this->client  = new \AlexaCRM\WebAPI\Client($clientFactory->getClient());
        } catch (\Exception $e) {
            log('CRM_connect_failed', $e->getMessage() . ' ' . $e->getCode());
        }
    }

The calls itself are made with:

$fetchExpression = new FetchExpression($fetchXML);
return json_encode($this->client->RetrieveMultiple($fetchExpression));

Do you see a possibility to speed this up?

One of my thoughts was, to make the client a singleton. But I don't think that this makes a difference, because I saw:

The library follows the lazy initialization pattern and doesn't actually validate the connection at client initialization time. To see how to handle errors, see below.

Hi @adrian-schnell

You're not using cache. Before the toolkit makes its first request to the Web API, it needs to do several things:

  • discover your tenant ID
  • perform authentication against Azure AD and acquire a token
  • download and analyze oData metadata

That's three roundtrips, and metadata is really heavy. Caching in the toolkit only looks like an option, because technically you could do without it. But some heavy lifting happens behind the doors, so you definitely need some for any production quality performance.

See the Tutorial -- it describes how to provide a PSR-6 compliant cache pool to the toolkit.

HTH

awesome @wizardist !
it's just the cache as you wrote.
I used https://packagist.org/packages/symfony/cache and ended in this init method:

            $settings                    = new OnlineSettings();
            $settings->instanceURI       = env('CRM_INSTANCE_URL', null);
            $settings->applicationID     = env('CRM_APPLICATION_ID', null);
            $settings->applicationSecret = env('CRM_APPLICATION_SECRET', null);

            $settings->cachePool = new FilesystemAdapter();

            $middleware = new OnlineAuthMiddleware($settings);

            $oDataClient  = new ODataClient($settings, $middleware);
            $this->client = new Client($oDataClient);