mirror of
https://github.com/facebook/sapling.git
synced 2024-10-08 07:49:11 +03:00
Use asyncio for 'eden start' systemd loop
Summary: 'eden start' polls for systemctl to exit, which is pretty gross. Use asyncio to avoid this explicit polling. (asyncio may still poll internally, though.) We still poll the log file. We could use inotify in the future to avoid polling. This refactor makes it easier to replace systemctl with direct D-Bus access in a future diff. This diff should not change behavior. Reviewed By: simpkins Differential Revision: D13526245 fbshipit-source-id: a29b1e062c489d8f2c70759e61765f8dd8df6664
This commit is contained in:
parent
444b73b83b
commit
d83cb71731
@ -7,6 +7,7 @@
|
||||
# LICENSE file in the root directory of this source tree. An additional grant
|
||||
# of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
import asyncio
|
||||
import errno
|
||||
import os
|
||||
import pathlib
|
||||
@ -215,19 +216,20 @@ def start_systemd_service(
|
||||
|
||||
startup_log_path = service_config.startup_log_file_path
|
||||
startup_log_path.write_bytes(b"")
|
||||
with forward_log_file( # pyre-ignore (T37455202)
|
||||
startup_log_path, sys.stderr.buffer
|
||||
) as log_forwarder:
|
||||
with subprocess.Popen(
|
||||
["systemctl", "--user", "start", "--", service_name]
|
||||
) as start_process:
|
||||
while True:
|
||||
log_forwarder.poll()
|
||||
exit_code = start_process.poll()
|
||||
if exit_code is not None:
|
||||
log_forwarder.poll()
|
||||
return exit_code
|
||||
time.sleep(0.1)
|
||||
with forward_log_file(startup_log_path, sys.stderr.buffer) as log_forwarder:
|
||||
loop = asyncio.get_event_loop()
|
||||
|
||||
async def start_service_async():
|
||||
start_process = await asyncio.create_subprocess_exec(
|
||||
"systemctl", "--user", "start", "--", service_name
|
||||
)
|
||||
return await start_process.wait()
|
||||
|
||||
start_task = loop.create_task(start_service_async())
|
||||
loop.create_task(log_forwarder.poll_forever_async())
|
||||
loop.run_until_complete(start_task)
|
||||
log_forwarder.poll()
|
||||
return start_task.result()
|
||||
|
||||
|
||||
def _get_daemon_args(
|
||||
|
@ -6,6 +6,7 @@
|
||||
# LICENSE file in the root directory of this source tree. An additional grant
|
||||
# of patent rights can be found in the PATENTS file in the same directory.
|
||||
|
||||
import asyncio
|
||||
import contextlib
|
||||
import io
|
||||
import pathlib
|
||||
@ -36,6 +37,11 @@ class LogForwarder:
|
||||
self.__output_file.write(self.__follower.poll())
|
||||
self.__output_file.flush()
|
||||
|
||||
async def poll_forever_async(self) -> typing.NoReturn:
|
||||
while True:
|
||||
self.poll()
|
||||
await asyncio.sleep(0.1)
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def follow_log_file(file_path: pathlib.Path) -> typing.Iterator["LogFollower"]:
|
||||
|
Loading…
Reference in New Issue
Block a user