1111# ///
1212import concurrent .futures
1313import io
14+ import os
1415import pathlib
1516from typing import Iterator , Optional
1617
3738RDM_TIMEZONE = "Europe/London"
3839SITE_URL = "https://stfc365.sharepoint.com/sites/ISISSustainability"
3940LAG_WINDOW_SECONDS = 24 * 60 * 60
41+ # It was observed that trying to load too many files concurrently from a sharepoint drive
42+ # randomly resulted in empty content. Lower the maximum number of threads that can be used
43+ # to extract the data
44+ MAX_WORKERS_DEFAULT = 10
4045
4146
4247def to_utc (ts : pd .Series ) -> pd .Series :
@@ -77,7 +82,7 @@ def read_power_consumption_excel(
7782def extract_content_and_read (
7883 items : Iterator [M365DriveItem ],
7984 skip_rows : int = dlt .config .value ,
80- max_threads : Optional [int ] = dlt .config .value ,
85+ max_workers : Optional [int ] = dlt .config .value ,
8186) -> Iterator [TDataItems ]:
8287 """Extracts the file content and reads it assuming it is a .csv or a .xlsx file
8388
@@ -86,7 +91,7 @@ def extract_content_and_read(
8691
8792 :param items: An iterator of dicts describing the file content
8893 :param skip_rows: Number of rows in the csv/xlsx files to skip
89- :param max_threads (optional): How many threads to use to process the files. Defaults to concurrent.futures.ThreadPoolExecutor default value.
94+ :param max_workers (optional): How many threads to use to process the files. Defaults to concurrent.futures.ThreadPoolExecutor default value.
9095 """
9196
9297 # The files are all independent. Process them in parallel and combine for a single yield
@@ -110,8 +115,12 @@ def read_as_dataframe(file_obj: M365DriveItem) -> pd.DataFrame | None:
110115
111116 return df
112117
118+ max_workers_request = (
119+ max_workers if max_workers is not None else MAX_WORKERS_DEFAULT
120+ )
121+ max_workers = min (max_workers_request , (os .cpu_count () or 1 ) + 4 )
113122 df_batch = None
114- with concurrent .futures .ThreadPoolExecutor (max_workers = max_threads ) as executor :
123+ with concurrent .futures .ThreadPoolExecutor (max_workers = max_workers ) as executor :
115124 future_to_file_item = {
116125 executor .submit (read_as_dataframe , file_obj ): file_obj for file_obj in items
117126 }
0 commit comments