omnata-plugin-runtime 0.4.6a102__tar.gz → 0.4.7__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/PKG-INFO +1 -1
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/pyproject.toml +1 -1
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/omnata_plugin.py +56 -45
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/rate_limiting.py +8 -3
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/LICENSE +0 -0
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/README.md +0 -0
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/__init__.py +0 -0
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/api.py +0 -0
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/configuration.py +0 -0
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/forms.py +0 -0
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/logging.py +0 -0
- {omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/plugin_entrypoints.py +0 -0
@@ -706,7 +706,7 @@ class OutboundSyncRequest(SyncRequest):
|
|
706
706
|
logger.info("applying results to table")
|
707
707
|
# use a random table name with a random string to avoid collisions
|
708
708
|
with self._snowflake_query_lock:
|
709
|
-
for attempt in Retrying(stop=stop_after_attempt(30),wait=wait_fixed(2),reraise=True,retry=retry_if_exception_message(match=".*is being committed.*")):
|
709
|
+
for attempt in Retrying(stop=stop_after_attempt(30),wait=wait_fixed(2),reraise=True,retry=retry_if_exception_message(match=".*(is being|was) committed.*")):
|
710
710
|
with attempt:
|
711
711
|
success, nchunks, nrows, _ = write_pandas(
|
712
712
|
conn=self._session._conn._cursor.connection, # pylint: disable=protected-access
|
@@ -1345,7 +1345,7 @@ class InboundSyncRequest(SyncRequest):
|
|
1345
1345
|
"""
|
1346
1346
|
if len(results_df) > 0:
|
1347
1347
|
with self._snowflake_query_lock:
|
1348
|
-
for attempt in Retrying(stop=stop_after_attempt(30),wait=wait_fixed(2),reraise=True,retry=retry_if_exception_message(match=".*is being committed.*")):
|
1348
|
+
for attempt in Retrying(stop=stop_after_attempt(30),wait=wait_fixed(2),reraise=True,retry=retry_if_exception_message(match=".*(is being|was) committed.*")):
|
1349
1349
|
with attempt:
|
1350
1350
|
logger.info(
|
1351
1351
|
f"Applying {len(results_df)} results to {self._full_results_table_name}"
|
@@ -1392,7 +1392,7 @@ class InboundSyncRequest(SyncRequest):
|
|
1392
1392
|
"""
|
1393
1393
|
if len(results_df) > 0:
|
1394
1394
|
with self._snowflake_query_lock:
|
1395
|
-
for attempt in Retrying(stop=stop_after_attempt(30),wait=wait_fixed(2),reraise=True,retry=retry_if_exception_message(match=".*is being committed.*")):
|
1395
|
+
for attempt in Retrying(stop=stop_after_attempt(30),wait=wait_fixed(2),reraise=True,retry=retry_if_exception_message(match=".*(is being|was) committed.*")):
|
1396
1396
|
with attempt:
|
1397
1397
|
logger.info(
|
1398
1398
|
f"Applying {len(results_df)} criteria deletes to {self._criteria_deletes_table_name}"
|
@@ -2097,50 +2097,61 @@ def managed_inbound_processing(concurrency: int):
|
|
2097
2097
|
|
2098
2098
|
tasks:List[threading.Thread] = []
|
2099
2099
|
logger.info(f"Creating {concurrency_to_use} worker(s) for retrieving records")
|
2100
|
-
|
2101
|
-
|
2102
|
-
|
2103
|
-
|
2104
|
-
|
2105
|
-
|
2106
|
-
|
2107
|
-
|
2108
|
-
|
2109
|
-
|
2110
|
-
streams_queue,
|
2111
|
-
self._sync_request._thread_cancellation_token,
|
2112
|
-
method_args,
|
2113
|
-
method_kwargs,
|
2114
|
-
),
|
2100
|
+
# if concurrency is set to 1, we don't need to use threads at all
|
2101
|
+
if concurrency_to_use == 1:
|
2102
|
+
__managed_inbound_processing_worker(
|
2103
|
+
self,
|
2104
|
+
method,
|
2105
|
+
0,
|
2106
|
+
streams_queue,
|
2107
|
+
self._sync_request._thread_cancellation_token,
|
2108
|
+
method_args,
|
2109
|
+
method_kwargs,
|
2115
2110
|
)
|
2116
|
-
tasks.append(task)
|
2117
|
-
task.start()
|
2118
|
-
|
2119
|
-
# wait for workers to finish
|
2120
|
-
while tasks:
|
2121
|
-
for task in tasks[:]: # shallow copy so we can remove items from the list while iterating
|
2122
|
-
if not task.is_alive():
|
2123
|
-
task.join() # Ensure the thread is fully finished
|
2124
|
-
tasks.remove(task)
|
2125
|
-
logger.info(f"Thread {task.name} has completed processing")
|
2126
|
-
time.sleep(1) # Avoid busy waiting
|
2127
|
-
logger.info("All workers completed processing")
|
2128
|
-
|
2129
|
-
# it's possible that some records weren't applied, since they are processed asynchronously on a timer
|
2130
|
-
#if self._sync_request.development_mode is False:
|
2131
|
-
# self._sync_request.apply_results_queue()
|
2132
|
-
#self._sync_request._thread_cancellation_token.set()
|
2133
|
-
## the thread cancellation should be detected by the apply results tasks, so it finishes gracefully
|
2134
|
-
#if (
|
2135
|
-
# self._sync_request.development_mode is False
|
2136
|
-
# and self._sync_request._apply_results_task is not None
|
2137
|
-
#):
|
2138
|
-
# self._sync_request._apply_results_task.join()
|
2139
|
-
if self._sync_request._thread_exception_thrown:
|
2140
|
-
logger.info("Raising thread exception")
|
2141
|
-
raise self._sync_request._thread_exception_thrown.exc_value
|
2142
2111
|
else:
|
2143
|
-
|
2112
|
+
for i in range(concurrency_to_use):
|
2113
|
+
# the dataframe/generator was put on the queue, so we remove it from the method args
|
2114
|
+
task = threading.Thread(
|
2115
|
+
target=__managed_inbound_processing_worker,
|
2116
|
+
name=f"managed_inbound_processing_worker_{i}",
|
2117
|
+
args=(
|
2118
|
+
self,
|
2119
|
+
method,
|
2120
|
+
i,
|
2121
|
+
streams_queue,
|
2122
|
+
self._sync_request._thread_cancellation_token,
|
2123
|
+
method_args,
|
2124
|
+
method_kwargs,
|
2125
|
+
),
|
2126
|
+
)
|
2127
|
+
tasks.append(task)
|
2128
|
+
task.start()
|
2129
|
+
|
2130
|
+
# wait for workers to finish
|
2131
|
+
while tasks:
|
2132
|
+
for task in tasks[:]: # shallow copy so we can remove items from the list while iterating
|
2133
|
+
if not task.is_alive():
|
2134
|
+
task.join() # Ensure the thread is fully finished
|
2135
|
+
tasks.remove(task)
|
2136
|
+
logger.info(f"Thread {task.name} has completed processing")
|
2137
|
+
time.sleep(1) # Avoid busy waiting
|
2138
|
+
logger.info("All workers completed processing")
|
2139
|
+
|
2140
|
+
# it's possible that some records weren't applied, since they are processed asynchronously on a timer
|
2141
|
+
#if self._sync_request.development_mode is False:
|
2142
|
+
# self._sync_request.apply_results_queue()
|
2143
|
+
#self._sync_request._thread_cancellation_token.set()
|
2144
|
+
## the thread cancellation should be detected by the apply results tasks, so it finishes gracefully
|
2145
|
+
#if (
|
2146
|
+
# self._sync_request.development_mode is False
|
2147
|
+
# and self._sync_request._apply_results_task is not None
|
2148
|
+
#):
|
2149
|
+
# self._sync_request._apply_results_task.join()
|
2150
|
+
if self._sync_request._thread_exception_thrown:
|
2151
|
+
logger.info("Raising thread exception")
|
2152
|
+
raise self._sync_request._thread_exception_thrown.exc_value
|
2153
|
+
else:
|
2154
|
+
logger.info("No thread exception thrown")
|
2144
2155
|
logger.info("Main managed_inbound_processing thread completing")
|
2145
2156
|
return
|
2146
2157
|
|
@@ -354,10 +354,15 @@ class RetryWithLogging(Retry):
|
|
354
354
|
"""
|
355
355
|
Adding extra logs before making a retry request
|
356
356
|
"""
|
357
|
-
def __init__(self, *args: Any,
|
358
|
-
self.thread_cancellation_token =
|
357
|
+
def __init__(self, *args: Any, **kwargs: Any) -> Any:
|
358
|
+
self.thread_cancellation_token:Optional[threading.Event] = None
|
359
359
|
return super().__init__(*args, **kwargs)
|
360
360
|
|
361
|
+
def new(self, **kw):
|
362
|
+
new_retry = super().new(**kw)
|
363
|
+
new_retry.thread_cancellation_token = self.thread_cancellation_token
|
364
|
+
return new_retry
|
365
|
+
|
361
366
|
def sleep_for_retry(self, response=None):
|
362
367
|
retry_after = self.get_retry_after(response)
|
363
368
|
if retry_after:
|
@@ -406,13 +411,13 @@ class RateLimitedSession(requests.Session):
|
|
406
411
|
self.statuses_to_include = statuses_to_include
|
407
412
|
|
408
413
|
retry_strategy = RetryWithLogging(
|
409
|
-
thread_cancellation_token=thread_cancellation_token,
|
410
414
|
total=max_retries,
|
411
415
|
backoff_factor=backoff_factor,
|
412
416
|
status_forcelist=statuses_to_include,
|
413
417
|
allowed_methods=["HEAD", "GET", "OPTIONS", "POST", "PUT", "DELETE"],
|
414
418
|
respect_retry_after_header=respect_retry_after_header
|
415
419
|
)
|
420
|
+
retry_strategy.thread_cancellation_token = thread_cancellation_token
|
416
421
|
adapter = HTTPAdapter(max_retries=retry_strategy)
|
417
422
|
self.mount("https://", adapter)
|
418
423
|
self.mount("http://", adapter)
|
File without changes
|
File without changes
|
File without changes
|
{omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/api.py
RENAMED
File without changes
|
File without changes
|
{omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/forms.py
RENAMED
File without changes
|
{omnata_plugin_runtime-0.4.6a102 → omnata_plugin_runtime-0.4.7}/src/omnata_plugin_runtime/logging.py
RENAMED
File without changes
|
File without changes
|