Skip to content

Commit 453dcf8

Browse files
authored
fix: add locking for braket_container for writes and local creation o… (#337)
1 parent eff1c22 commit 453dcf8

File tree

1 file changed

+36
-15
lines changed

1 file changed

+36
-15
lines changed

src/braket_container.py

+36-15
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import contextlib
1414
import errno
1515
import importlib
16+
import threading
1617
import inspect
1718
import os
1819
import json
@@ -36,6 +37,12 @@
3637
ERROR_LOG_FILE = os.path.join(ERROR_LOG_PATH, "failure")
3738
SETUP_SCRIPT_PATH = os.path.join(OPT_BRAKET, "additional_setup")
3839

40+
_local = threading.local()
41+
_error_log_lock = threading.Lock()
42+
_path_lock = threading.Lock()
43+
_chdir_lock = threading.Lock()
44+
_unpack_lock = threading.Lock()
45+
3946
print("Boto3 Version: ", boto3.__version__)
4047

4148

@@ -47,12 +54,13 @@ def _log_failure(*args, display=True):
4754
Args:
4855
args: variable list of text to write to the file.
4956
"""
50-
Path(ERROR_LOG_PATH).mkdir(parents=True, exist_ok=True)
51-
with open(ERROR_LOG_FILE, 'a') as error_log:
52-
for text in args:
53-
error_log.write(text)
54-
if display:
55-
print(text)
57+
with _error_log_lock:
58+
Path(ERROR_LOG_PATH).mkdir(parents=True, exist_ok=True)
59+
with open(ERROR_LOG_FILE, 'a') as error_log:
60+
for text in args:
61+
error_log.write(text)
62+
if display:
63+
print(text)
5664

5765

5866
def log_failure_and_exit(*args):
@@ -91,6 +99,12 @@ def create_symlink():
9199
log_failure_and_exit(f"Symlink failure.\n Exception: {e}")
92100

93101

102+
def get_s3_client():
103+
if not hasattr(_local, 's3_client'):
104+
_local.s3_client = boto3.client("s3")
105+
return _local.s3_client
106+
107+
94108
def download_s3_file(s3_uri: str, local_path: str) -> str:
95109
"""
96110
Downloads a file to a local path.
@@ -101,7 +115,8 @@ def download_s3_file(s3_uri: str, local_path: str) -> str:
101115
Returns:
102116
str: the path to the file containing the downloaded path.
103117
"""
104-
s3_client = boto3.client("s3")
118+
119+
s3_client = get_s3_client()
105120
parsed_url = urlparse(s3_uri, allow_fragments=False)
106121
s3_bucket = parsed_url.netloc
107122
s3_key = parsed_url.path.lstrip("/")
@@ -138,15 +153,18 @@ def unpack_code_and_add_to_path(local_s3_file: str, compression_type: str):
138153
"""
139154
if compression_type and compression_type.strip().lower() in ["gzip", "zip"]:
140155
try:
141-
shutil.unpack_archive(local_s3_file, EXTRACTED_CUSTOMER_CODE_PATH)
156+
with _unpack_lock:
157+
shutil.unpack_archive(local_s3_file, EXTRACTED_CUSTOMER_CODE_PATH)
142158
except Exception as e:
143159
log_failure_and_exit(
144160
f"Got an exception while trying to unpack archive: {local_s3_file} of type: "
145161
f"{compression_type}.\nException: {e}"
146162
)
147163
else:
148164
shutil.copy(local_s3_file, EXTRACTED_CUSTOMER_CODE_PATH)
149-
sys.path.append(EXTRACTED_CUSTOMER_CODE_PATH)
165+
with _path_lock:
166+
if EXTRACTED_CUSTOMER_CODE_PATH not in sys.path:
167+
sys.path.append(EXTRACTED_CUSTOMER_CODE_PATH)
150168

151169

152170
def try_bind_hyperparameters_to_customer_method(customer_method: Callable):
@@ -243,12 +261,13 @@ def customer_code():
243261

244262
@contextlib.contextmanager
245263
def in_extracted_code_dir():
246-
current_dir = os.getcwd()
247-
try:
248-
os.chdir(EXTRACTED_CUSTOMER_CODE_PATH)
249-
yield
250-
finally:
251-
os.chdir(current_dir)
264+
with _chdir_lock:
265+
current_dir = os.getcwd()
266+
try:
267+
os.chdir(EXTRACTED_CUSTOMER_CODE_PATH)
268+
yield
269+
finally:
270+
os.chdir(current_dir)
252271

253272

254273
def wrap_customer_code(customer_method: Callable) -> Callable:
@@ -301,6 +320,8 @@ def join_customer_script(customer_code_process: multiprocessing.Process):
301320
try:
302321
customer_code_process.join()
303322
except Exception as e:
323+
customer_code_process.terminate()
324+
customer_code_process.join()
304325
log_failure_and_exit(f"Job did not exit gracefully.\nException: {e}")
305326
print("Code Run Finished")
306327
return customer_code_process.exitcode

0 commit comments

Comments
 (0)