|
1 | 1 | # main.py |
2 | 2 | from pyscript import PyWorker, document, window |
| 3 | +import js |
3 | 4 |
|
4 | 5 | # ---- Initialize Ace Editor from Python ---- |
5 | 6 | # Create the editor |
|
21 | 22 | await worker.ready |
22 | 23 |
|
23 | 24 | async def run(event): |
| 25 | + global worker |
| 26 | + |
24 | 27 | code = editor.getValue() |
25 | | - result = await worker.sync.evaluate(code) |
26 | | - document.getElementById("output").innerText = f"Results:\n {result}" |
| 28 | + document.getElementById("output").innerText = "⏳ Running..." |
| 29 | + |
| 30 | + # ---- TIMEOUT HANDLING ---- |
| 31 | + timeout_ms = 1500 # 1.5 second limit |
| 32 | + |
| 33 | + # Create a promise that wraps worker.sync.evaluate |
| 34 | + eval_promise = worker.sync.evaluate(code) |
| 35 | + |
| 36 | + # Create the timeout promise |
| 37 | + timeout_promise = window.Promise.new( |
| 38 | + lambda resolve, reject: |
| 39 | + window.setTimeout(lambda: reject(Exception("timeout")), timeout_ms) |
| 40 | + ) |
| 41 | + |
| 42 | + try: |
| 43 | + # Race the worker call vs. timeout |
| 44 | + result = await window.Promise.race([eval_promise, timeout_promise]) |
| 45 | + |
| 46 | + document.getElementById("output").innerText = f"{result}" |
| 47 | + |
| 48 | + except Exception as e: |
| 49 | + if str(e) == "Error: timeout": |
| 50 | + # ---- Worker hung. Kill it. ---- |
| 51 | + worker.terminate() |
| 52 | + worker = make_worker() # start fresh |
| 53 | + await worker.ready |
| 54 | + document.getElementById("output").innerText = ( |
| 55 | + "💥 Your code took too long (possible infinite loop). Worker reset." |
| 56 | + ) |
| 57 | + else: |
| 58 | + document.getElementById("output").innerText = f"💥 Error: {e}" |
27 | 59 |
|
28 | 60 | document.getElementById("run").addEventListener("click", run) |
29 | 61 |
|
0 commit comments