Skip to content

Commit

Permalink
Use weakref.finalize() to shutdown server connection (#580)
Browse files Browse the repository at this point in the history
  • Loading branch information
pkrull-ansys authored Nov 22, 2024
1 parent d953dc1 commit 03984b4
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 3 deletions.
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ build-backend = "flit_core.buildapi"
[project]
# Check https://flit.readthedocs.io/en/latest/pyproject_toml.html for all available sections
name = "ansys-additive-core"
version = "0.20.dev1"
version = "0.20.dev2"
description = "A Python client for the Ansys Additive service"
readme = "README.rst"
requires-python = ">=3.10,<4"
Expand Down
13 changes: 11 additions & 2 deletions src/ansys/additive/core/server_connection/server_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import logging
import os
import time
import weakref
from dataclasses import dataclass

import grpc
Expand Down Expand Up @@ -118,6 +119,8 @@ def __init__(
) -> None:
"""Initialize a server connection."""

weakref.finalize(self, self.disconnect)

if channel and addr:
raise ValueError("Both 'channel' and 'addr' cannot both be specified.")

Expand Down Expand Up @@ -158,12 +161,18 @@ def __init__(

self._log.info("Connected to %s", self.channel_str)

def __del__(self):
"""Destructor for cleaning up server connection."""
def __del__(self) -> None:
"""Disconnect from server."""
self.disconnect()

def disconnect(self):
"""Clean up server connection."""
if hasattr(self, "_server_instance") and self._server_instance:
self._server_instance.delete()
self._server_instance = None
if hasattr(self, "_server_process") and self._server_process:
self._server_process.kill()
self._server_process = None

@property
def channel_str(self) -> str:
Expand Down
66 changes: 66 additions & 0 deletions tests/server_connection/test_server_connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

from subprocess import Popen
from unittest.mock import ANY, Mock, create_autospec

import grpc
Expand Down Expand Up @@ -347,3 +348,68 @@ def test_server_connection_status_str_connected_with_metadata():
# assert
expected_str = "Server localhost:50051 is connected.\n version: 1.0\n status: running"
assert status_str == expected_str


def test_disconnect_with_server_instance(monkeypatch):
# arrange
mock_ready = create_autospec(
ansys.additive.core.server_connection.server_connection.ServerConnection.ready,
return_value=True,
)
monkeypatch.setattr(
ansys.additive.core.server_connection.server_connection.ServerConnection,
"ready",
mock_ready,
)
mock_server_instance = Mock(pypim.Instance)
server = ServerConnection(channel=grpc.insecure_channel("target"))
server._server_instance = mock_server_instance

# act
server.disconnect()

# assert
mock_server_instance.delete.assert_called_once()


def test_disconnect_with_server_process(monkeypatch):
# arrange
mock_ready = create_autospec(
ansys.additive.core.server_connection.server_connection.ServerConnection.ready,
return_value=True,
)
monkeypatch.setattr(
ansys.additive.core.server_connection.server_connection.ServerConnection,
"ready",
mock_ready,
)
mock_server_process = Mock(Popen)
server = ServerConnection(channel=grpc.insecure_channel("target"))
server._server_process = mock_server_process

# act
server.disconnect()

# assert
mock_server_process.kill.assert_called_once()


def test_disconnect_with_no_server_instance_or_process(monkeypatch):
# arrange
mock_ready = create_autospec(
ansys.additive.core.server_connection.server_connection.ServerConnection.ready,
return_value=True,
)
monkeypatch.setattr(
ansys.additive.core.server_connection.server_connection.ServerConnection,
"ready",
mock_ready,
)
server = ServerConnection(channel=grpc.insecure_channel("target"))

# act
server.disconnect()

# assert
# No exception should be raised and no methods should be called
assert True

0 comments on commit 03984b4

Please sign in to comment.