Skip to content

Commit bd2a952

Browse files
authored
FIX: prefer_streaming=True now returns all file links (#92)
* properly return a list of links, selected by the fastest host that returns a response * tests now require actual OPENDAP links to get partitioned
1 parent 49b9b64 commit bd2a952

2 files changed

Lines changed: 37 additions & 5 deletions

File tree

intake_esgf/base.py

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
92113
def 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

intake_esgf/tests/test_basic.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,17 +151,18 @@ def test_partition_infos():
151151

152152

153153
def test_partition_infos_stream():
154+
VALID_OPENDAP_LINK = "https://esgf-data1.llnl.gov/thredds/dodsC/css03_data/CMIP6/CMIP/AS-RCEC/TaiESM1/historical/r1i1p1f1/day/tasmax/gn/v20210517/tasmax_day_TaiESM1_historical_r1i1p1f1_gn_20100101-20141231.nc"
154155
infos = [
155156
{
156157
"key": "dataset1",
157158
"path": Path("file1"),
158-
"VirtualZarr": ["link1", "link2"],
159+
"VirtualZarr": [VALID_OPENDAP_LINK, VALID_OPENDAP_LINK],
159160
},
160161
{
161162
"key": "dataset2",
162163
"path": Path("file1"),
163164
"HTTPServer": ["link1", "link2"],
164-
"OPENDAP": ["link1", "link2"],
165+
"OPENDAP": [VALID_OPENDAP_LINK, VALID_OPENDAP_LINK],
165166
},
166167
]
167168
infos_, ds = partition_infos(infos, False, False)

0 commit comments

Comments
 (0)