Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion tableauserverclient/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# For when a datasource is over 64MB, break it into 5MB(standard chunk size) chunks
CHUNK_SIZE_MB = 5 * 10 # 5MB felt too slow, upped it to 50

DELAY_SLEEP_SECONDS = 10
DELAY_SLEEP_SECONDS = 0.1

# The maximum size of a file that can be published in a single request is 64MB
FILESIZE_LIMIT_MB = 64
45 changes: 22 additions & 23 deletions tableauserverclient/server/endpoint/endpoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
from time import sleep
from tableauserverclient import datetime_helpers as datetime

import requests
from packaging.version import Version
from functools import wraps
from xml.etree.ElementTree import ParseError
Expand Down Expand Up @@ -76,7 +75,7 @@ def set_user_agent(parameters):
# return explicitly for testing only
return parameters

def _blocking_request(self, method, url, parameters={}) -> Optional["Response"]:
def _blocking_request(self, method, url, parameters={}) -> Optional[Union["Response", Exception]]:
self.async_response = None
response = None
logger.debug("[{}] Begin blocking request to {}".format(datetime.timestamp(), url))
Expand All @@ -95,39 +94,37 @@ def _blocking_request(self, method, url, parameters={}) -> Optional["Response"]:
return self.async_response

def send_request_while_show_progress_threaded(
self, method, url, parameters={}, request_timeout=0
) -> Optional["Response"]:
self, method, url, parameters={}, request_timeout=None
) -> Optional[Union["Response", Exception]]:
try:
request_thread = Thread(target=self._blocking_request, args=(method, url, parameters))
request_thread.async_response = -1 # type:ignore # this is an invented attribute for thread comms
request_thread.start()
except Exception as e:
logger.debug("Error starting server request on separate thread: {}".format(e))
return None
seconds = 0
seconds = 0.05
minutes = 0
sleep(1)
if self.async_response != -1:
last_log_minute = 0
sleep(seconds)
if self.async_response is not None:
# a quick return for any immediate responses
return self.async_response
while self.async_response == -1 and (request_timeout == 0 or seconds < request_timeout):
self.log_wait_time_then_sleep(minutes, seconds, url)
timed_out: bool = request_timeout is not None and seconds > request_timeout
while (self.async_response is None) and not timed_out:
sleep(DELAY_SLEEP_SECONDS)
seconds = seconds + DELAY_SLEEP_SECONDS
if seconds >= 60:
seconds = 0
minutes = minutes + 1
minutes = int(seconds / 60)
last_log_minute = self.log_wait_time(minutes, last_log_minute, url)
return self.async_response

def log_wait_time_then_sleep(self, minutes, seconds, url):
def log_wait_time(self, minutes, last_log_minute, url) -> int:
logger.debug("{} Waiting....".format(datetime.timestamp()))
if seconds >= 60: # detailed log message ~every minute
if minutes % 5 == 0:
logger.info(
"[{}] Waiting ({} minutes so far) for request to {}".format(datetime.timestamp(), minutes, url)
)
else:
logger.debug("[{}] Waiting for request to {}".format(datetime.timestamp(), url))
sleep(DELAY_SLEEP_SECONDS)
if minutes > last_log_minute: # detailed log message ~every minute
logger.info("[{}] Waiting ({} minutes so far) for request to {}".format(datetime.timestamp(), minutes, url))
last_log_minute = minutes
else:
logger.debug("[{}] Waiting for request to {}".format(datetime.timestamp(), url))
return last_log_minute

def _make_request(
self,
Expand All @@ -151,7 +148,7 @@ def _make_request(
# a request can, for stuff like publishing, spin for ages waiting for a response.
# we need some user-facing activity so they know it's not dead.
request_timeout = self.parent_srv.http_options.get("timeout") or 0
server_response: Optional["Response"] = self.send_request_while_show_progress_threaded(
server_response: Optional[Union["Response", Exception]] = self.send_request_while_show_progress_threaded(
method, url, parameters, request_timeout
)
logger.debug("[{}] Async request returned: received {}".format(datetime.timestamp(), server_response))
Expand All @@ -163,6 +160,8 @@ def _make_request(
if server_response is None:
logger.debug("[{}] Request failed".format(datetime.timestamp()))
raise RuntimeError
if isinstance(server_response, Exception):
raise server_response
self._check_status(server_response, url)

loggable_response = self.log_response_safely(server_response)
Expand Down