update_manager: fix blocking I/O

When using tempfile.TemporaryDirectory it is possible that
exiting the context will block when attempting to delete
the temporary directory.  Don't use the context manager,
instead create and cleanup the temp dir using the default
threadpoolexecutor.

Signed-off-by:  Eric Callahan <arksine.code@gmail.com>
This commit is contained in:
Eric Callahan 2022-02-28 19:30:34 -05:00
parent faf956c65d
commit 27466984df
No known key found for this signature in database
GPG Key ID: 7027245FBBDDF59A
2 changed files with 17 additions and 7 deletions

View File

@ -602,6 +602,13 @@ class CommandHelper:
self.notify_update_response(
f"Downloading {self.cur_update_app}: {totals} [{progress}%]")
async def create_tempdir(self, suffix=None, prefix=None):
def _createdir(sfx, pfx):
return tempfile.TemporaryDirectory(suffix=sfx, prefix=pfx)
eventloop = self.server.get_event_loop()
return await eventloop.run_in_thread(_createdir, suffix, prefix)
class PackageDeploy(BaseDeploy):
def __init__(self,
config: ConfigHelper,
@ -1218,9 +1225,9 @@ class WebClientDeploy(BaseDeploy):
f"Updating Web Client {self.name}...")
self.cmd_helper.notify_update_response(
f"Downloading Client: {self.name}")
with tempfile.TemporaryDirectory(
suffix=self.name, prefix="client") as tempdirname:
tempdir = pathlib.Path(tempdirname)
td = await self.cmd_helper.create_tempdir(self.name, "client")
try:
tempdir = pathlib.Path(td.name)
temp_download_file = tempdir.joinpath(f"{self.name}.zip")
temp_persist_dir = tempdir.joinpath(self.name)
client = self.cmd_helper.get_http_client()
@ -1232,6 +1239,8 @@ class WebClientDeploy(BaseDeploy):
await event_loop.run_in_thread(
self._extract_release, temp_persist_dir,
temp_download_file)
finally:
await event_loop.run_in_thread(td.cleanup)
self.version = self.remote_version
version_path = self.path.joinpath(".version")
if not version_path.exists():

View File

@ -11,7 +11,6 @@ import json
import shutil
import re
import time
import tempfile
import zipfile
from .app_deploy import AppDeploy
from utils import verify_source
@ -378,9 +377,9 @@ class ZipDeploy(AppDeploy):
npm_hash = await self._get_file_hash(self.npm_pkg_json)
dl_url, content_type, size = self.release_download_info
self.notify_status("Starting Download...")
with tempfile.TemporaryDirectory(
suffix=self.name, prefix="app") as tempdirname:
tempdir = pathlib.Path(tempdirname)
td = await self.cmd_helper.create_tempdir(self.name, "app")
try:
tempdir = pathlib.Path(td.name)
temp_download_file = tempdir.joinpath(f"{self.name}.zip")
client = self.cmd_helper.get_http_client()
await client.download_file(
@ -391,6 +390,8 @@ class ZipDeploy(AppDeploy):
event_loop = self.server.get_event_loop()
await event_loop.run_in_thread(
self._extract_release, temp_download_file)
finally:
await event_loop.run_in_thread(td.cleanup)
await self._update_dependencies(npm_hash, force=force_dep_update)
await self._update_repo_state()
await self.restart_service()