mirror of
https://github.com/facebook/sapling.git
synced 2024-12-26 06:21:48 +03:00
introduce a py3 client
Summary: Introduce a py3 replacement for EdenClient. Reviewed By: wez Differential Revision: D22060644 fbshipit-source-id: 535a1f1addf3ac79de0471a688cef55567802d26
This commit is contained in:
parent
80e710e70d
commit
62f06c645a
70
eden/fs/py/eden/thrift/client.py
Normal file
70
eden/fs/py/eden/thrift/client.py
Normal file
@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This software may be used and distributed according to the terms of the
|
||||
# GNU General Public License version 2.
|
||||
|
||||
import os
|
||||
from typing import Optional
|
||||
|
||||
from eden.fs.service.eden.clients import EdenService
|
||||
from thrift.py3 import get_client
|
||||
from thrift.py3.exceptions import TransportError, TransportErrorType
|
||||
|
||||
|
||||
SOCKET_PATH = "socket"
|
||||
|
||||
|
||||
class EdenNotRunningError(Exception):
|
||||
def __init__(self, socket_path: str):
|
||||
super(EdenNotRunningError, self).__init__(
|
||||
f"edenfs daemon does not appear to be running: tried {socket_path}"
|
||||
)
|
||||
self.socket_path = socket_path
|
||||
|
||||
|
||||
class EdenClient(EdenService):
|
||||
"""
|
||||
EdenClient is a subclass of EdenService that provides
|
||||
some conveniences and helps deal with evolving Thrift APIs.
|
||||
"""
|
||||
|
||||
socket_path: Optional[str] = None
|
||||
|
||||
async def __aenter__(self):
|
||||
try:
|
||||
return await super().__aenter__()
|
||||
except TransportError as ex:
|
||||
if ex.type == TransportErrorType.NOT_OPEN:
|
||||
raise EdenNotRunningError(self.socket_path)
|
||||
raise
|
||||
|
||||
|
||||
def create_thrift_client(
|
||||
eden_dir: Optional[str] = None,
|
||||
socket_path: Optional[str] = None,
|
||||
timeout: Optional[float] = None,
|
||||
) -> EdenClient:
|
||||
"""
|
||||
Construct a thrift client to speak to the running eden server
|
||||
instance associated with the specified mount point.
|
||||
|
||||
@return Returns an EdenService.Client.
|
||||
"""
|
||||
|
||||
if socket_path is not None:
|
||||
pass
|
||||
elif eden_dir is not None:
|
||||
socket_path = os.path.join(eden_dir, SOCKET_PATH)
|
||||
else:
|
||||
raise TypeError("one of eden_dir or socket_path is required")
|
||||
|
||||
if timeout is None:
|
||||
# We used to set a default timeout here, but picking the right duration is hard,
|
||||
# and safely retrying an arbitrary thrift call may not be safe. So we
|
||||
# just leave the client with no timeout, unless one is given.
|
||||
timeout = 0
|
||||
|
||||
client = get_client(EdenClient, path=socket_path, timeout=timeout)
|
||||
client.socket_path = socket_path
|
||||
return client
|
26
eden/fs/py/eden/thrift/test/client_test.py
Normal file
26
eden/fs/py/eden/thrift/test/client_test.py
Normal file
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This software may be used and distributed according to the terms of the
|
||||
# GNU General Public License version 2.
|
||||
|
||||
import os.path
|
||||
import tempfile
|
||||
import unittest
|
||||
|
||||
from eden.thrift.client import EdenNotRunningError, create_thrift_client
|
||||
|
||||
|
||||
class EdenClientTest(unittest.IsolatedAsyncioTestCase):
|
||||
async def test_raise_EdenNotRunningError_when_no_socket(self):
|
||||
with tempfile.TemporaryDirectory() as td:
|
||||
sockname = os.path.join(td, "sock")
|
||||
with self.assertRaises(EdenNotRunningError) as cm:
|
||||
async with create_thrift_client(socket_path=sockname):
|
||||
pass
|
||||
ex = cm.exception
|
||||
self.assertEqual(sockname, ex.socket_path)
|
||||
self.assertEqual(
|
||||
"edenfs daemon does not appear to be running: tried " + sockname,
|
||||
str(ex),
|
||||
)
|
Loading…
Reference in New Issue
Block a user