Service Providers¶
Service providers are background services which can should be started on
on the initialized
notification from the client.
A good example of a service is a code indexing service which watches the file system and indexes code when files change.
Example¶
A full example of a service provider:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <?php namespace Phpactor\LanguageServer\Example\Service; use Amp\CancellationToken; use Amp\CancelledException; use Amp\Delayed; use Amp\Promise; use Phpactor\LanguageServer\Core\Server\ClientApi; use Phpactor\LanguageServer\Core\Service\ServiceProvider; /** * Example service which shows a "ping" message every second. */ class PingProvider implements ServiceProvider { /** * @var ClientApi */ private $client; public function __construct(ClientApi $client) { $this->client = $client; } /** * {@inheritDoc} */ public function services(): array { return [ 'ping' ]; } /** * @return Promise<null> */ public function ping(CancellationToken $cancel): Promise { return \Amp\call(function () use ($cancel) { while (true) { try { $cancel->throwIfRequested(); } catch (CancelledException $cancelled) { break; } yield new Delayed(1000); $this->client->window()->showMessage()->info('ping'); } }); } } |
This is similar to method handlers with the exception that:
- The
services
method provides only an array of method names. The name doubles as both the method and service name. - The method is called when the Language Server is initialized (or when it is started via. the service manager).
- Services are passed only a
CancellationToken
.
Usage¶
<?php
$serviceProviders = new ServiceProviders(
new PingProvider($clientApi)
);
$serviceManager = new ServiceManager($serviceProviders, $logger);
$eventDispatcher = new EventDispatcher(
new ServiceListener($serviceManager)
);
$handlers = new Handlers(
// ...
new ServiceHandler($serviceManager, $clientApi),
// ...
);
return new MiddlewareDispatcher(
// ...
new InitializeMiddleware($handlers, $eventDispatcher)
// ...
);
In the above code the ServiceManager
is responsible for starting and
stopping services, the ServiceHandler
handles RPC methods to start/stop
services, and we use the ServiceListener
to start the services when the
server is initialized (based on the Initialized
event issued by the
InitializeMiddleware
.