22from time import sleep
33from tableauserverclient import datetime_helpers as datetime
44
5- import requests
65from packaging .version import Version
76from functools import wraps
87from xml .etree .ElementTree import ParseError
@@ -76,7 +75,7 @@ def set_user_agent(parameters):
7675 # return explicitly for testing only
7776 return parameters
7877
79- def _blocking_request (self , method , url , parameters = {}) -> Optional ["Response" ]:
78+ def _blocking_request (self , method , url , parameters = {}) -> Optional [Union [ "Response" , Exception ] ]:
8079 self .async_response = None
8180 response = None
8281 logger .debug ("[{}] Begin blocking request to {}" .format (datetime .timestamp (), url ))
@@ -95,39 +94,37 @@ def _blocking_request(self, method, url, parameters={}) -> Optional["Response"]:
9594 return self .async_response
9695
9796 def send_request_while_show_progress_threaded (
98- self , method , url , parameters = {}, request_timeout = 0
99- ) -> Optional ["Response" ]:
97+ self , method , url , parameters = {}, request_timeout = None
98+ ) -> Optional [Union [ "Response" , Exception ] ]:
10099 try :
101100 request_thread = Thread (target = self ._blocking_request , args = (method , url , parameters ))
102- request_thread .async_response = - 1 # type:ignore # this is an invented attribute for thread comms
103101 request_thread .start ()
104102 except Exception as e :
105103 logger .debug ("Error starting server request on separate thread: {}" .format (e ))
106104 return None
107- seconds = 0
105+ seconds = 0.05
108106 minutes = 0
109- sleep (1 )
110- if self .async_response != - 1 :
107+ last_log_minute = 0
108+ sleep (seconds )
109+ if self .async_response is not None :
111110 # a quick return for any immediate responses
112111 return self .async_response
113- while self .async_response == - 1 and (request_timeout == 0 or seconds < request_timeout ):
114- self .log_wait_time_then_sleep (minutes , seconds , url )
112+ timed_out : bool = request_timeout is not None and seconds > request_timeout
113+ while (self .async_response is None ) and not timed_out :
114+ sleep (DELAY_SLEEP_SECONDS )
115115 seconds = seconds + DELAY_SLEEP_SECONDS
116- if seconds >= 60 :
117- seconds = 0
118- minutes = minutes + 1
116+ minutes = int (seconds / 60 )
117+ last_log_minute = self .log_wait_time (minutes , last_log_minute , url )
119118 return self .async_response
120119
121- def log_wait_time_then_sleep (self , minutes , seconds , url ):
120+ def log_wait_time (self , minutes , last_log_minute , url ) -> int :
122121 logger .debug ("{} Waiting...." .format (datetime .timestamp ()))
123- if seconds >= 60 : # detailed log message ~every minute
124- if minutes % 5 == 0 :
125- logger .info (
126- "[{}] Waiting ({} minutes so far) for request to {}" .format (datetime .timestamp (), minutes , url )
127- )
128- else :
129- logger .debug ("[{}] Waiting for request to {}" .format (datetime .timestamp (), url ))
130- sleep (DELAY_SLEEP_SECONDS )
122+ if minutes > last_log_minute : # detailed log message ~every minute
123+ logger .info ("[{}] Waiting ({} minutes so far) for request to {}" .format (datetime .timestamp (), minutes , url ))
124+ last_log_minute = minutes
125+ else :
126+ logger .debug ("[{}] Waiting for request to {}" .format (datetime .timestamp (), url ))
127+ return last_log_minute
131128
132129 def _make_request (
133130 self ,
@@ -151,7 +148,7 @@ def _make_request(
151148 # a request can, for stuff like publishing, spin for ages waiting for a response.
152149 # we need some user-facing activity so they know it's not dead.
153150 request_timeout = self .parent_srv .http_options .get ("timeout" ) or 0
154- server_response : Optional ["Response" ] = self .send_request_while_show_progress_threaded (
151+ server_response : Optional [Union [ "Response" , Exception ] ] = self .send_request_while_show_progress_threaded (
155152 method , url , parameters , request_timeout
156153 )
157154 logger .debug ("[{}] Async request returned: received {}" .format (datetime .timestamp (), server_response ))
@@ -163,6 +160,8 @@ def _make_request(
163160 if server_response is None :
164161 logger .debug ("[{}] Request failed" .format (datetime .timestamp ()))
165162 raise RuntimeError
163+ if isinstance (server_response , Exception ):
164+ raise server_response
166165 self ._check_status (server_response , url )
167166
168167 loggable_response = self .log_response_safely (server_response )
0 commit comments