|
23 | 23 | import json
|
24 | 24 | import types
|
25 | 25 | import functools
|
| 26 | +import sys |
26 | 27 | import tempfile
|
27 | 28 | import time
|
28 | 29 | from typing import Union, Optional, Dict, Any
|
@@ -91,7 +92,7 @@ def download_url(url, proxies=None):
|
91 | 92 | Returns:
|
92 | 93 | `str`: The location of the temporary file where the url was downloaded.
|
93 | 94 | """
|
94 |
| - return http_get(url, tempfile.gettempdir(), download_file_name='tmp_' + url.split('/')[-1], proxies=proxies) |
| 95 | + return threads_exclusive_http_get(url, tempfile.gettempdir(), download_file_name='tmp_' + url.split('/')[-1], proxies=proxies) |
95 | 96 |
|
96 | 97 | def copy_func(f):
|
97 | 98 | """Returns a copy of a function f."""
|
@@ -142,6 +143,25 @@ def get_cache_path():
|
142 | 143 | return cache_dir
|
143 | 144 |
|
144 | 145 |
|
| 146 | +def threads_exclusive_http_get(url, storage_folder=None, md5sum=None, download_file_name=None, proxies=None, headers=None): |
| 147 | + pointer_path = os.path.join(storage_folder, download_file_name) |
| 148 | + lock_file_path = pointer_path + ".lock" |
| 149 | + if sys.platform != "win32": |
| 150 | + import fcntl # pylint: disable=import-error |
| 151 | + else: |
| 152 | + import winfcntlock as fcntl # pylint: disable=import-error |
| 153 | + with open(lock_file_path, 'w') as lock_file: |
| 154 | + fd = lock_file.fileno() |
| 155 | + try: |
| 156 | + fcntl.flock(fd, fcntl.LOCK_EX) |
| 157 | + file_path = http_get(url, path=storage_folder, download_file_name=download_file_name, proxies=proxies, headers=headers) |
| 158 | + return file_path |
| 159 | + except Exception as exp: |
| 160 | + raise exp |
| 161 | + finally: |
| 162 | + fcntl.flock(fd, fcntl.LOCK_UN) |
| 163 | + |
| 164 | + |
145 | 165 | def http_get(url, path=None, md5sum=None, download_file_name=None, proxies=None, headers=None):
|
146 | 166 | r"""
|
147 | 167 | Download from given url, save to path.
|
@@ -628,11 +648,11 @@ def download(
|
628 | 648 | else:
|
629 | 649 | headers = {}
|
630 | 650 | try:
|
631 |
| - pointer_path = http_get(url, storage_folder, download_file_name=relative_filename, proxies=proxies, headers=headers) |
632 |
| - except Exception: |
| 651 | + pointer_path = threads_exclusive_http_get(url, storage_folder, download_file_name=relative_filename, proxies=proxies, headers=headers) |
| 652 | + except Exception as exp: |
633 | 653 | # Otherwise, our Internet connection is down.
|
634 | 654 | # etag is None
|
635 |
| - raise |
| 655 | + raise exp |
636 | 656 |
|
637 | 657 | return pointer_path
|
638 | 658 |
|
@@ -723,7 +743,7 @@ def get_from_cache(
|
723 | 743 | if os.path.exists(file_path) and check_md5(file_path, md5sum):
|
724 | 744 | return file_path
|
725 | 745 | try:
|
726 |
| - path = http_get(url, cache_dir, md5sum, download_file_name=filename, proxies=proxies) |
| 746 | + path = threads_exclusive_http_get(url, cache_dir, md5sum, download_file_name=filename, proxies=proxies) |
727 | 747 | return path
|
728 | 748 | except (ProxyError, SSLError) as exc:
|
729 | 749 | raise exc
|
|
0 commit comments