@@ -89,6 +89,27 @@ def get_globus_endpoints(info: dict) -> list[str]:
8989 return globus_endpoints
9090
9191
92+ def select_streaming_link (links : list [str ], df_rate : pd .DataFrame ) -> str :
93+ """
94+ Select a streaming link from a list of options based on fastest download speeds.
95+ """
96+ # There are some .nc and .nc.html links in these records, only the .nc links
97+ # can be read by xarray.
98+ links = [link for link in links if link .endswith (".nc" )]
99+ # Sort the links by the fastest hostname we have seen when transferring.
100+ links = sorted (
101+ links , key = partial (sort_download_links , df_rate = df_rate ), reverse = True
102+ )
103+ # Return the first of these links whose html page returns a valid response.
104+ # This is particular to OPENDAP and will need rethought for other virtual
105+ # methods.
106+ for link in links :
107+ resp = requests .get (link + ".html" , stream = True , timeout = 10 )
108+ if resp .status_code == 200 :
109+ return link
110+ raise ValueError (f"None of these links appears functional { links } " )
111+
112+
92113def partition_infos (
93114 infos : list [dict ], prefer_streaming : bool , prefer_globus : bool
94115) -> tuple [dict , dict ]:
@@ -132,6 +153,9 @@ def partition_infos(
132153 active_endpoints = set ()
133154
134155 # Partition and setup all the file infos based on a priority
156+ df_rate = get_download_rate_dataframe (
157+ Path (intake_esgf .conf ["download_db" ]).expanduser ()
158+ )
135159 for i , info in enumerate (infos ):
136160 key = info ["key" ]
137161
@@ -151,16 +175,23 @@ def partition_infos(
151175
152176 # 2) does the user prefer to stream data?
153177 if prefer_streaming :
154- # how do we choose a link ?
178+ # What possible links are there to stream from ?
155179 preferred_sources = ["VirtualZarr" , "OPENDAP" ] # move to configure
156180 links = [
157181 link
158182 for src in (set (preferred_sources ) & set (info ))
159183 for link in info [src ]
160184 ]
161185 if links :
162- # for now just use first link, we need to do better
163- ds [key ] = [links [0 ]]
186+ # Try to find a streaming link from the fastest servers we have
187+ # seen while downloading. If this fails, we revert to https.
188+ try :
189+ link = select_streaming_link (links , df_rate )
190+ except ValueError :
191+ break
192+ if key not in ds :
193+ ds [key ] = []
194+ ds [key ].append (link )
164195 infos_stream .append (info ) # maybe not needed
165196 continue
166197
0 commit comments