Skip to content

Commit 7284611

Browse files
authored
Pilot 6372: add status check after uploading (#204)
* add upload status at the end of upload/resumable upload * fix up test cases * update new version messagge if clickable link is not showing up
1 parent 1847d4b commit 7284611

File tree

9 files changed

+46
-39
lines changed

9 files changed

+46
-39
lines changed

app/configs/user_config.py

+1
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ def __init__(
5858
5959
This adjustment is made to prevent complications with mounted NFS volumes where all files have root ownership.
6060
"""
61+
6162
if config_path is None:
6263
config_path = ConfigClass.config_path
6364
if config_filename is None:

app/services/crypto/crypto.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -75,5 +75,4 @@ def decryption(encrypted_message, secret, interactive=True):
7575
ehandler.SrvErrorHandler.default_handle(str(ex) + ', please try login as a valid user.')
7676
else:
7777
raise ex
78-
else:
79-
ehandler.SrvErrorHandler.customized_handle(ehandler.ECustomizedError.LOGIN_SESSION_INVALID, True)
78+
return ''

app/services/file_manager/file_upload/file_upload.py

+17-8
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,13 @@ def simple_upload( # noqa: C901
254254
pool.close()
255255
pool.join()
256256

257-
if attribute:
258-
continue_loop = True
259-
while continue_loop:
260-
# the last uploaded file
261-
succeed = upload_client.check_status(file_object)
262-
continue_loop = not succeed
263-
time.sleep(0.5)
257+
unfinished_files = pre_upload_infos
258+
while len(unfinished_files) > 0:
259+
temp = []
260+
mhandler.SrvOutPutHandler.finalize_upload()
261+
for file_batchs in batch_generator(pre_upload_infos, batch_size=AppConfig.Env.upload_batch_size):
262+
temp.extend(upload_client.check_status(file_batchs))
263+
unfinished_files = temp
264264

265265
num_of_file = len(pre_upload_infos)
266266
logger.info(f'Upload Time: {time.time() - upload_start_time:.2f}s for {num_of_file:d} files')
@@ -341,7 +341,7 @@ def resume_upload(
341341
# out of thread pool.
342342
res = pool.apply_async(
343343
upload_client.on_succeed,
344-
args=(file_object),
344+
args=(file_object,),
345345
)
346346
on_success_res.append(res)
347347

@@ -353,5 +353,14 @@ def resume_upload(
353353
pool.close()
354354
pool.join()
355355

356+
unfinished_files = unfinished_items
357+
while len(unfinished_files) > 0:
358+
temp = []
359+
mhandler.SrvOutPutHandler.finalize_upload()
360+
for file_batchs in batch_generator(unfinished_items, batch_size=AppConfig.Env.upload_batch_size):
361+
temp.extend(upload_client.check_status(file_batchs))
362+
unfinished_files = temp
363+
time.sleep(1)
364+
356365
num_of_file = len(unfinished_items)
357366
logger.info(f'Upload Time: {time.time() - upload_start_time:.2f}s for {num_of_file:d} files')

app/services/file_manager/file_upload/upload_client.py

+14-11
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
from app.services.output_manager.error_handler import ECustomizedError
3030
from app.services.output_manager.error_handler import SrvErrorHandler
3131
from app.services.user_authentication.decorator import require_valid_token
32+
from app.utils.aggregated import ItemStatus
3233
from app.utils.aggregated import get_file_info_by_geid
3334

3435
from .exception import INVALID_CHUNK_ETAG
@@ -354,10 +355,11 @@ def on_complete(result):
354355

355356
# for resumable check ONLY if user resume the upload at 100%
356357
# just check if there is any active job, if not, set the event
357-
while not chunk_upload_done.wait(timeout=60):
358+
while not chunk_upload_done.wait(timeout=5):
358359
if self.active_jobs == 0:
359360
chunk_upload_done.set()
360-
logger.warning('Waiting for all the chunks to be uploaded, remaining jobs: %s', file_object.progress)
361+
else:
362+
logger.warning('Waiting for all the chunks to be uploaded, remaining jobs: %s', self.active_jobs)
361363

362364
f.close()
363365

@@ -447,7 +449,7 @@ def on_succeed(self, file_object: FileObject) -> None:
447449
result = response.json().get('result')
448450
return result
449451

450-
def check_status(self, file_object: FileObject) -> bool:
452+
def check_status(self, file_objects: list[FileObject]) -> list[FileObject]:
451453
"""
452454
Summary:
453455
The function is to check the status of upload process.
@@ -458,14 +460,15 @@ def check_status(self, file_object: FileObject) -> bool:
458460
- bool: if job success or not
459461
"""
460462

461-
# with pre-register upload, we can check if the file entity is already exist
462-
# if exist, we can continue with manifest process
463-
file_entity = get_file_info_by_geid([file_object.item_id])[0].get('result', {})
464-
mhandler.SrvOutPutHandler.finalize_upload()
465-
if file_entity.get('status') == 'ACTIVE':
466-
return True
467-
else:
468-
return False
463+
file_ids = [file_object.item_id for file_object in file_objects]
464+
results = get_file_info_by_geid(file_ids)
465+
unfinished_files = []
466+
for r in results:
467+
status = r.get('status')
468+
if status != ItemStatus.ACTIVE:
469+
unfinished_files.append(r.get('result'))
470+
471+
return unfinished_files
469472

470473
def set_finish_upload(self):
471474
self.finish_upload = True

app/services/output_manager/message_handler.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,8 @@ def newer_version_available(version, download_url, print_message=True):
356356
clickable_text = f'\033]8;;{download_url}\033\\latest cli version\033]8;;\033\\'
357357
message = (
358358
f'\nNewer version available! Pilotcli v{version} is available. Please vist \n{clickable_text}. '
359-
'This link will expire in 10 minutes.\n'
359+
'This link will expire in 10 minutes. If the link doesn\'t show up, Please visit the \n'
360+
'support page on portal to download the latest version.'
360361
)
361362
if print_message:
362363
logger.warning(message)

app/utils/aggregated.py

-9
Original file line numberDiff line numberDiff line change
@@ -234,24 +234,15 @@ def remove_the_output_file(filepath: str) -> None:
234234

235235

236236
def get_latest_cli_version() -> Tuple[Version, str]:
237-
import logging
238-
import time
239237

240238
try:
241-
start_time = time.time()
242239
httpx_client = BaseClient(AppConfig.Connections.url_fileops_greenroom)
243-
logging.critical(f'http client init time: {time.time() - start_time}')
244240
user_config = UserConfig()
245-
logging.critical(f'user config init time: {time.time() - start_time}')
246-
t1 = time.time()
247241
if not user_config.is_access_token_exists():
248242
return Version('0.0.0')
249-
logging.critical(f'Check token time: {time.time() - t1}')
250-
t2 = time.time()
251243

252244
headers = {'Authorization': 'Bearer'}
253245
response = httpx_client._get('v1/download/cli/presigned', headers=headers)
254-
logging.critical(f'Get latest version time: {time.time() - t2}')
255246
result = response.json().get('result', {})
256247
latest_version = result.get('linux', {}).get('version', '0.0.0')
257248
download_url = result.get('linux', {}).get('download_url', '')

pyproject.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "app"
3-
version = "3.14.0"
3+
version = "3.14.1"
44
description = "This service is designed to support pilot platform"
55
authors = ["Indoc Systems"]
66

tests/app/services/file_manager/file_upload/test_upload_client.py

+9-6
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import pytest
1414

1515
from app.configs.app_config import AppConfig
16+
from app.models.item import ItemStatus
1617
from app.services.file_manager.file_upload.exception import INVALID_CHUNK_ETAG
1718
from app.services.file_manager.file_upload.models import FileObject
1819
from app.services.file_manager.file_upload.upload_client import UploadClient
@@ -39,14 +40,14 @@ def test_check_status_success(httpx_mock, mocker):
3940
httpx_mock.add_response(
4041
method='POST',
4142
url=AppConfig.Connections.url_bff + '/v1/query/geid',
42-
json={'result': [{'result': {'filename': 'test', 'status': 'ACTIVE'}}]},
43+
json={'result': [{'status': ItemStatus.ACTIVE, 'result': {'name': 'test', 'status': ItemStatus.ACTIVE}}]},
4344
status_code=200,
4445
)
4546

4647
test_obj = FileObject('test', 'test', 'test', 'test', 'test')
47-
result = upload_client.check_status(test_obj)
48+
result = upload_client.check_status([test_obj])
4849

49-
assert result is True
50+
assert len(result) == 0
5051

5152

5253
def test_check_status_fail(httpx_mock, mocker):
@@ -58,14 +59,16 @@ def test_check_status_fail(httpx_mock, mocker):
5859
httpx_mock.add_response(
5960
method='POST',
6061
url=AppConfig.Connections.url_bff + '/v1/query/geid',
61-
json={'result': [{'result': {'filename': 'test', 'status': 'REGISTERED'}}]},
62+
json={
63+
'result': [{'status': ItemStatus.REGISTERED, 'result': {'name': 'test', 'status': ItemStatus.REGISTERED}}]
64+
},
6265
status_code=200,
6366
)
6467

6568
test_obj = FileObject('test', 'test', 'test', 'test', 'test')
66-
result = upload_client.check_status(test_obj)
69+
result = upload_client.check_status([test_obj])
6770

68-
assert result is False
71+
assert len(result) == 1
6972

7073

7174
def test_chunk_upload(httpx_mock, mocker):

tests/conftest.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def mock_upload_client(monkeypatch):
5252
monkeypatch.setattr(UploadClient, 'stream_upload', lambda *args, **kwargs: [])
5353
monkeypatch.setattr(UploadClient, 'on_succeed', lambda *args, **kwargs: None)
5454
monkeypatch.setattr(UploadClient, 'output_manifest', lambda *args, **kwargs: {})
55-
monkeypatch.setattr(UploadClient, 'check_status', lambda *args, **kwargs: True)
55+
monkeypatch.setattr(UploadClient, 'check_status', lambda *args, **kwargs: [])
5656

5757

5858
@pytest.fixture

0 commit comments

Comments
 (0)