Skip to content

Commit 2c0fee2

Browse files
fix: work around segfault with >100 jobs in google life sciences backend (snakemake#1451)
* refactor _retry_request to avoid segfault * fmt * reworking _get_services to use auth_http * fix mistake in retry_request * remove imports outside of func Co-authored-by: Johannes Köster <[email protected]>
1 parent 086f60f commit 2c0fee2

File tree

1 file changed

+47
-12
lines changed

1 file changed

+47
-12
lines changed

snakemake/executors/google_lifesciences.py

Lines changed: 47 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from snakemake.common import get_container_image, get_file_hash
2424
from snakemake.resources import DefaultResources
2525

26+
2627
# https://github.com/googleapis/google-api-python-client/issues/299#issuecomment-343255309
2728
logging.getLogger("googleapiclient.discovery_cache").setLevel(logging.ERROR)
2829

@@ -139,28 +140,56 @@ def _get_services(self):
139140
for storage.
140141
"""
141142
from googleapiclient.discovery import build as discovery_build
142-
from oauth2client.client import (
143-
GoogleCredentials,
144-
ApplicationDefaultCredentialsError,
145-
)
146143
from google.cloud import storage
144+
import google.auth
145+
import google_auth_httplib2
146+
import httplib2
147+
import googleapiclient
147148

148149
# Credentials must be exported to environment
149150
try:
150-
creds = GoogleCredentials.get_application_default()
151-
except ApplicationDefaultCredentialsError as ex:
151+
# oauth2client is deprecated, see: https://google-auth.readthedocs.io/en/master/oauth2client-deprecation.html
152+
# google.auth is replacement
153+
# not sure about scopes here. this cover all cloud services
154+
creds, _ = google.auth.default(
155+
scopes=["https://www.googleapis.com/auth/cloud-platform"]
156+
)
157+
except google.auth.DefaultCredentialsError as ex:
152158
log_verbose_traceback(ex)
153159
raise ex
154160

161+
def build_request(http, *args, **kwargs):
162+
"""
163+
See https://googleapis.github.io/google-api-python-client/docs/thread_safety.html
164+
"""
165+
new_http = google_auth_httplib2.AuthorizedHttp(creds, http=httplib2.Http())
166+
return googleapiclient.http.HttpRequest(new_http, *args, **kwargs)
167+
155168
# Discovery clients for Google Cloud Storage and Life Sciences API
169+
# create authorized http for building services
170+
authorized_http = google_auth_httplib2.AuthorizedHttp(
171+
creds, http=httplib2.Http()
172+
)
156173
self._storage_cli = discovery_build(
157-
"storage", "v1", credentials=creds, cache_discovery=False
174+
"storage",
175+
"v1",
176+
cache_discovery=False,
177+
requestBuilder=build_request,
178+
http=authorized_http,
158179
)
159180
self._compute_cli = discovery_build(
160-
"compute", "v1", credentials=creds, cache_discovery=False
181+
"compute",
182+
"v1",
183+
cache_discovery=False,
184+
requestBuilder=build_request,
185+
http=authorized_http,
161186
)
162187
self._api = discovery_build(
163-
"lifesciences", "v2beta", credentials=creds, cache_discovery=False
188+
"lifesciences",
189+
"v2beta",
190+
cache_discovery=False,
191+
requestBuilder=build_request,
192+
http=authorized_http,
164193
)
165194
self._bucket_service = storage.Client()
166195

@@ -903,18 +932,24 @@ def _retry_request(self, request, timeout=2, attempts=3):
903932
except BrokenPipeError as ex:
904933
if attempts > 0:
905934
time.sleep(timeout)
906-
return self._retry_request(request, timeout * 2, attempts - 1)
935+
return self._retry_request(
936+
request, timeout=timeout * 2, attempts=attempts - 1
937+
)
907938
raise ex
908939
except googleapiclient.errors.HttpError as ex:
909940
if attempts > 0:
910941
time.sleep(timeout)
911-
return self._retry_request(request, timeout * 2, attempts - 1)
942+
return self._retry_request(
943+
request, timeout=timeout * 2, attempts=attempts - 1
944+
)
912945
log_verbose_traceback(ex)
913946
raise ex
914947
except Exception as ex:
915948
if attempts > 0:
916949
time.sleep(timeout)
917-
return self._retry_request(request, timeout * 2, attempts - 1)
950+
return self._retry_request(
951+
request, timeout=timeout * 2, attempts=attempts - 1
952+
)
918953
log_verbose_traceback(ex)
919954
raise ex
920955

0 commit comments

Comments
 (0)