ni.datamonikers.v1.client 0.1.0.dev0__tar.gz → 0.1.0.dev1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: ni.datamonikers.v1.client
3
- Version: 0.1.0.dev0
3
+ Version: 0.1.0.dev1
4
4
  Summary: gRPC Client for NI Data Moniker Service
5
5
  License: MIT
6
6
  Keywords: data-moniker,client
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "ni.datamonikers.v1.client"
3
- version = "0.1.0-dev0"
3
+ version = "0.1.0-dev1"
4
4
  license = "MIT"
5
5
  description = "gRPC Client for NI Data Moniker Service"
6
6
  authors = [{name = "NI", email = "opensource@ni.com"}]
@@ -3,14 +3,23 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import logging
6
+ import sys
6
7
  import threading
7
- from typing import Iterator
8
+ from types import TracebackType
9
+ from typing import TYPE_CHECKING, Iterator
8
10
 
9
11
  import grpc
10
12
  import ni.datamonikers.v1.data_moniker_pb2 as data_moniker_pb2
11
13
  import ni.datamonikers.v1.data_moniker_pb2_grpc as data_moniker_pb2_grpc
12
14
  from ni_grpc_extensions.channelpool import GrpcChannelPool
13
15
 
16
+ if TYPE_CHECKING:
17
+ if sys.version_info >= (3, 11):
18
+ from typing import Self
19
+ else:
20
+ from typing_extensions import Self
21
+
22
+
14
23
  _logger = logging.getLogger(__name__)
15
24
 
16
25
 
@@ -18,13 +27,15 @@ class MonikerClient:
18
27
  """Client for accessing the NI Data Moniker Service."""
19
28
 
20
29
  __slots__ = (
21
- "_initialization_lock",
30
+ "_lock",
31
+ "_owns_grpc_channel_pool",
22
32
  "_service_location",
23
33
  "_grpc_channel_pool",
24
34
  "_stub",
25
35
  )
26
36
 
27
- _initialization_lock: threading.Lock
37
+ _lock: threading.Lock
38
+ _owns_grpc_channel_pool: bool
28
39
  _service_location: str | None
29
40
  _grpc_channel_pool: GrpcChannelPool | None
30
41
  _stub: data_moniker_pb2_grpc.MonikerServiceStub | None
@@ -51,7 +62,8 @@ class MonikerClient:
51
62
  if service_location is None and grpc_channel is None:
52
63
  raise ValueError("Either 'service_location' or 'grpc_channel' must be provided.")
53
64
 
54
- self._initialization_lock = threading.Lock()
65
+ self._lock = threading.Lock()
66
+ self._owns_grpc_channel_pool = False
55
67
  self._service_location = service_location
56
68
  self._grpc_channel_pool = grpc_channel_pool
57
69
  self._stub = (
@@ -60,12 +72,35 @@ class MonikerClient:
60
72
  else None
61
73
  )
62
74
 
75
+ def __enter__(self) -> Self:
76
+ """Enter the runtime context of the MonikerClient."""
77
+ return self
78
+
79
+ def __exit__(
80
+ self,
81
+ exc_type: type[BaseException] | None,
82
+ exc_val: BaseException | None,
83
+ traceback: TracebackType | None,
84
+ ) -> None:
85
+ """Exit the runtime context of the MonikerClient."""
86
+ self.close()
87
+
88
+ def close(self) -> None:
89
+ """Close the client and clean up resources that it owns."""
90
+ with self._lock:
91
+ self._stub = None
92
+ if self._owns_grpc_channel_pool and self._grpc_channel_pool:
93
+ self._grpc_channel_pool.close()
94
+ self._grpc_channel_pool = None
95
+ self._owns_grpc_channel_pool = False
96
+
63
97
  def _get_stub(self) -> data_moniker_pb2_grpc.MonikerServiceStub:
64
98
  if self._stub is None:
65
- with self._initialization_lock:
99
+ with self._lock:
66
100
  if self._grpc_channel_pool is None:
67
101
  _logger.debug("Creating unshared GrpcChannelPool.")
68
102
  self._grpc_channel_pool = GrpcChannelPool()
103
+ self._owns_grpc_channel_pool = True
69
104
 
70
105
  if self._stub is None:
71
106
  channel = self._grpc_channel_pool.get_channel(self._service_location) # type: ignore