Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -368,6 +368,52 @@ with gr.Blocks() as interface:
|
|
368 |
print(f"❌ Failed to log submission to Google Sheets: {e}")
|
369 |
|
370 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
371 |
|
372 |
def threaded_batch_runner(file=None, text="", email=""):
|
373 |
print("📧 EMAIL RECEIVED:", repr(email))
|
|
|
368 |
print(f"❌ Failed to log submission to Google Sheets: {e}")
|
369 |
|
370 |
|
371 |
+
import multiprocessing
|
372 |
+
import time
|
373 |
+
|
374 |
+
def run_with_timeout(func, args=(), kwargs={}, timeout=30, stop_value=None):
|
375 |
+
"""
|
376 |
+
Runs func in a separate process with optional timeout.
|
377 |
+
If stop_value is provided and becomes True during execution, the process is killed early.
|
378 |
+
"""
|
379 |
+
def wrapper(q, *args, **kwargs):
|
380 |
+
try:
|
381 |
+
result = func(*args, **kwargs)
|
382 |
+
q.put((True, result))
|
383 |
+
except Exception as e:
|
384 |
+
q.put((False, e))
|
385 |
+
|
386 |
+
q = multiprocessing.Queue()
|
387 |
+
p = multiprocessing.Process(target=wrapper, args=(q, *args), kwargs=kwargs)
|
388 |
+
p.start()
|
389 |
+
|
390 |
+
start_time = time.time()
|
391 |
+
while p.is_alive():
|
392 |
+
# Timeout check
|
393 |
+
if timeout is not None and (time.time() - start_time) > timeout:
|
394 |
+
p.terminate()
|
395 |
+
p.join()
|
396 |
+
print(f"⏱️ Timeout exceeded ({timeout} sec) — function killed.")
|
397 |
+
return False, None
|
398 |
+
|
399 |
+
# Stop flag check
|
400 |
+
if stop_value is not None and stop_value.value:
|
401 |
+
p.terminate()
|
402 |
+
p.join()
|
403 |
+
print("🛑 Stop flag detected — function killed early.")
|
404 |
+
return False, None
|
405 |
+
|
406 |
+
time.sleep(0.1) # avoid busy waiting
|
407 |
+
|
408 |
+
# Process finished naturally
|
409 |
+
if not q.empty():
|
410 |
+
success, result = q.get()
|
411 |
+
if success:
|
412 |
+
return True, result
|
413 |
+
else:
|
414 |
+
raise result
|
415 |
+
|
416 |
+
return False, None
|
417 |
|
418 |
def threaded_batch_runner(file=None, text="", email=""):
|
419 |
print("📧 EMAIL RECEIVED:", repr(email))
|