2
2
from time import sleep
3
3
from tableauserverclient import datetime_helpers as datetime
4
4
5
- import requests
6
5
from packaging .version import Version
7
6
from functools import wraps
8
7
from xml .etree .ElementTree import ParseError
@@ -76,7 +75,7 @@ def set_user_agent(parameters):
76
75
# return explicitly for testing only
77
76
return parameters
78
77
79
- def _blocking_request (self , method , url , parameters = {}) -> Optional ["Response" ]:
78
+ def _blocking_request (self , method , url , parameters = {}) -> Optional [Union [ "Response" , Exception ] ]:
80
79
self .async_response = None
81
80
response = None
82
81
logger .debug ("[{}] Begin blocking request to {}" .format (datetime .timestamp (), url ))
@@ -95,39 +94,37 @@ def _blocking_request(self, method, url, parameters={}) -> Optional["Response"]:
95
94
return self .async_response
96
95
97
96
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 ] ]:
100
99
try :
101
100
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
103
101
request_thread .start ()
104
102
except Exception as e :
105
103
logger .debug ("Error starting server request on separate thread: {}" .format (e ))
106
104
return None
107
- seconds = 0
105
+ seconds = 0.05
108
106
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 :
111
110
# a quick return for any immediate responses
112
111
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 )
115
115
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 )
119
118
return self .async_response
120
119
121
- def log_wait_time_then_sleep (self , minutes , seconds , url ):
120
+ def log_wait_time (self , minutes , last_log_minute , url ) -> int :
122
121
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
131
128
132
129
def _make_request (
133
130
self ,
@@ -151,7 +148,7 @@ def _make_request(
151
148
# a request can, for stuff like publishing, spin for ages waiting for a response.
152
149
# we need some user-facing activity so they know it's not dead.
153
150
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 (
155
152
method , url , parameters , request_timeout
156
153
)
157
154
logger .debug ("[{}] Async request returned: received {}" .format (datetime .timestamp (), server_response ))
@@ -163,6 +160,8 @@ def _make_request(
163
160
if server_response is None :
164
161
logger .debug ("[{}] Request failed" .format (datetime .timestamp ()))
165
162
raise RuntimeError
163
+ if isinstance (server_response , Exception ):
164
+ raise server_response
166
165
self ._check_status (server_response , url )
167
166
168
167
loggable_response = self .log_response_safely (server_response )
0 commit comments