From fa7273b328b8cea8b051917f5255a1a712a9e1b9 Mon Sep 17 00:00:00 2001 From: Astounds Date: Sat, 28 Mar 2026 16:06:47 -0500 Subject: fix: race condition in os.makedirs causing worker crashes Replace check-then-create pattern with exist_ok=True to prevent FileExistsError when multiple workers initialize simultaneously. Affects: - subscriptions.py: open_database() - watch.py: save_decrypt_cache() - local_playlist.py: add_to_playlist() - util.py: fetch_url(), get_visitor_data() - settings.py: initialization Fixes Gunicorn worker startup failures in multi-worker deployments. --- youtube/local_playlist.py | 3 +-- youtube/subscriptions.py | 3 +-- youtube/util.py | 6 ++---- youtube/watch.py | 7 ++----- 4 files changed, 6 insertions(+), 13 deletions(-) (limited to 'youtube') diff --git a/youtube/local_playlist.py b/youtube/local_playlist.py index aa3ac27..968f1a6 100644 --- a/youtube/local_playlist.py +++ b/youtube/local_playlist.py @@ -26,8 +26,7 @@ def video_ids_in_playlist(name): def add_to_playlist(name, video_info_list): - if not os.path.exists(playlists_directory): - os.makedirs(playlists_directory) + os.makedirs(playlists_directory, exist_ok=True) ids = video_ids_in_playlist(name) missing_thumbnails = [] with open(os.path.join(playlists_directory, name + ".txt"), "a", encoding='utf-8') as file: diff --git a/youtube/subscriptions.py b/youtube/subscriptions.py index 3326a51..980822a 100644 --- a/youtube/subscriptions.py +++ b/youtube/subscriptions.py @@ -30,8 +30,7 @@ database_path = os.path.join(settings.data_dir, "subscriptions.sqlite") def open_database(): - if not os.path.exists(settings.data_dir): - os.makedirs(settings.data_dir) + os.makedirs(settings.data_dir, exist_ok=True) connection = sqlite3.connect(database_path, check_same_thread=False) try: diff --git a/youtube/util.py b/youtube/util.py index ebb5307..3f48c84 100644 --- a/youtube/util.py +++ b/youtube/util.py @@ -343,8 +343,7 @@ def fetch_url(url, headers=(), timeout=15, report_text=None, data=None, and debug_name is not None and content): save_dir = os.path.join(settings.data_dir, 'debug') - if not os.path.exists(save_dir): - os.makedirs(save_dir) + os.makedirs(save_dir, exist_ok=True) with open(os.path.join(save_dir, debug_name), 'wb') as f: f.write(content) @@ -902,8 +901,7 @@ INNERTUBE_CLIENTS = { def get_visitor_data(): visitor_data = None visitor_data_cache = os.path.join(settings.data_dir, 'visitorData.txt') - if not os.path.exists(settings.data_dir): - os.makedirs(settings.data_dir) + os.makedirs(settings.data_dir, exist_ok=True) if os.path.isfile(visitor_data_cache): with open(visitor_data_cache, 'r') as file: print('Getting visitor_data from cache') diff --git a/youtube/watch.py b/youtube/watch.py index 360fbc9..332a9d5 100644 --- a/youtube/watch.py +++ b/youtube/watch.py @@ -329,11 +329,8 @@ def get_ordered_music_list_attributes(music_list): def save_decrypt_cache(): - try: - f = open(os.path.join(settings.data_dir, 'decrypt_function_cache.json'), 'w') - except FileNotFoundError: - os.makedirs(settings.data_dir) - f = open(os.path.join(settings.data_dir, 'decrypt_function_cache.json'), 'w') + os.makedirs(settings.data_dir, exist_ok=True) + f = open(os.path.join(settings.data_dir, 'decrypt_function_cache.json'), 'w') f.write(json.dumps({'version': 1, 'decrypt_cache':decrypt_cache}, indent=4, sort_keys=True)) f.close() -- cgit v1.2.3