From 415d3ea9fb575d56e142e8136c4222b77204e84f Mon Sep 17 00:00:00 2001 From: Dillon Nys Date: Wed, 2 Apr 2025 08:53:26 -0700 Subject: [PATCH] chore(cloud): Improve gRPC interface - Add separate `.http` and `.grpc` dedicated constructors - Allow specifying an `InternetAddress` for the gRPC host, e.g. a UNIX socket --- packages/celest_cloud/CHANGELOG.md | 1 + .../celest_cloud/lib/src/cloud/cloud.dart | 93 +++++++++++++++---- .../lib/src/cloud/cloud_protocol.grpc.dart | 31 ++++--- 3 files changed, 97 insertions(+), 28 deletions(-) diff --git a/packages/celest_cloud/CHANGELOG.md b/packages/celest_cloud/CHANGELOG.md index 1edaa275a..2a2125ab4 100644 --- a/packages/celest_cloud/CHANGELOG.md +++ b/packages/celest_cloud/CHANGELOG.md @@ -2,6 +2,7 @@ - feat: Add `Operations.waitOperation` - chore: Update license +- chore: Improve gRPC interface # 0.1.4 diff --git a/packages/celest_cloud/lib/src/cloud/cloud.dart b/packages/celest_cloud/lib/src/cloud/cloud.dart index afc672707..34aa60426 100644 --- a/packages/celest_cloud/lib/src/cloud/cloud.dart +++ b/packages/celest_cloud/lib/src/cloud/cloud.dart @@ -1,3 +1,6 @@ +/// @docImport 'dart:io'; +library; + import 'package:celest_cloud/src/cloud/authentication/authentication.dart'; import 'package:celest_cloud/src/cloud/cloud_protocol.dart'; import 'package:celest_cloud/src/cloud/cloud_protocol.grpc.dart'; @@ -15,32 +18,90 @@ import 'package:os_detect/os_detect.dart' as os; import 'package:protobuf/protobuf.dart'; class CelestCloud { - CelestCloud({ + factory CelestCloud({ required Uri uri, Authenticator authenticator = const Authenticator.static(), ClientType? clientType, Logger? logger, String? userAgent, http.Client? httpClient, - }) : _protocol = kIsWeb - ? CloudProtocolHttp( - uri: uri, - httpClient: httpClient, - authenticator: authenticator, - logger: logger, - ) - : CloudProtocolGrpc( - uri: uri, - userAgent: userAgent, - authenticator: authenticator, - logger: logger, - ), + }) { + return kIsWeb + ? CelestCloud.http( + uri, + authenticator: authenticator, + clientType: clientType, + logger: logger, + httpClient: httpClient, + ) + : CelestCloud.grpc( + uri, + authenticator: authenticator, + clientType: clientType, + logger: logger, + userAgent: userAgent, + httpClient: httpClient, + ); + } + + CelestCloud._({ + required CloudProtocol protocol, + Uri? uri, + Authenticator authenticator = const Authenticator.static(), + ClientType? clientType, + Logger? logger, + http.Client? httpClient, + }) : _protocol = protocol, _baseUri = uri, _httpClient = httpClient, _authenticator = authenticator, _clientType = clientType ?? _defaultClientType, _logger = logger ?? Logger('Celest.Cloud'); + CelestCloud.http( + Uri uri, { + Authenticator authenticator = const Authenticator.static(), + ClientType? clientType, + Logger? logger, + http.Client? httpClient, + }) : this._( + uri: uri, + authenticator: authenticator, + protocol: CloudProtocolHttp( + uri: uri, + httpClient: httpClient, + authenticator: authenticator, + logger: logger, + ), + clientType: clientType, + logger: logger, + httpClient: httpClient, + ); + + /// Creates a gRPC interface for Celest Cloud. + /// + /// [address] must be either a [Uri] or [InternetAddress]. + CelestCloud.grpc( + Object address, { + Authenticator authenticator = const Authenticator.static(), + ClientType? clientType, + String? userAgent, + Logger? logger, + http.Client? httpClient, + }) : this._( + uri: address is Uri ? address : null, + authenticator: authenticator, + protocol: CloudProtocolGrpc( + host: address, + userAgent: userAgent, + authenticator: authenticator, + logger: logger, + ), + clientType: clientType, + logger: logger, + httpClient: httpClient, + ); + static final _defaultClientType = kIsWeb ? ClientType.WEB : os.isAndroid @@ -63,7 +124,7 @@ class CelestCloud { ProjectEnvironment(), ]); - final Uri _baseUri; + final Uri? _baseUri; final http.Client? _httpClient; final Authenticator _authenticator; @@ -72,7 +133,7 @@ class CelestCloud { final Logger _logger; late final CloudProtocolHttp _httpProtocol = CloudProtocolHttp( - uri: _baseUri, + uri: _baseUri!, authenticator: _authenticator, httpClient: _httpClient, logger: _logger, diff --git a/packages/celest_cloud/lib/src/cloud/cloud_protocol.grpc.dart b/packages/celest_cloud/lib/src/cloud/cloud_protocol.grpc.dart index 6d0a7481c..5851dfc1f 100644 --- a/packages/celest_cloud/lib/src/cloud/cloud_protocol.grpc.dart +++ b/packages/celest_cloud/lib/src/cloud/cloud_protocol.grpc.dart @@ -18,26 +18,33 @@ import 'package:logging/logging.dart'; final class CloudProtocolGrpc implements CloudProtocol { CloudProtocolGrpc({ - required Uri uri, + required Object host, required Authenticator authenticator, String? userAgent, Logger? logger, }) : _channel = AuthenticatingGrpcChannel( - uri.host, + switch (host) { + final Uri uri => uri.host, + _ => host, + }, authenticator: authenticator, options: ChannelOptions( - credentials: uri.scheme == 'http' - ? const ChannelCredentials.insecure() - : const ChannelCredentials.secure(), + credentials: switch (host) { + Uri(scheme: 'https') => const ChannelCredentials.secure(), + _ => const ChannelCredentials.insecure(), + }, userAgent: userAgent ?? 'celest/dart', ), - port: uri.hasPort - ? uri.port - : switch (uri.scheme) { - 'http' => 80, - 'https' => 443, - _ => throw Exception('Unsupported scheme: ${uri.scheme}'), - }, + port: switch (host) { + final Uri uri => uri.hasPort + ? uri.port + : switch (uri.scheme) { + 'http' => 80, + 'https' => 443, + _ => throw Exception('Unsupported scheme: ${uri.scheme}'), + }, + _ => 50051, + }, ), _interceptors = [ RevokingGrpcInterceptor(