Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -447,32 +447,49 @@ class CodeExecutor:
|
|
| 447 |
|
| 448 |
return self._combine_results(results, main_files)
|
| 449 |
|
|
|
|
|
|
|
| 450 |
async def _execute_java(
|
| 451 |
self,
|
| 452 |
main_files: List[str],
|
| 453 |
workspace: str,
|
| 454 |
input_data: Optional[List[str]] = None,
|
| 455 |
) -> ExecutionResult:
|
| 456 |
-
"""Compile and execute Java code with input support"""
|
| 457 |
-
|
| 458 |
# Check if we have .java files to compile
|
| 459 |
java_files = list(Path(workspace).glob("*.java"))
|
| 460 |
needs_compilation = len(java_files) > 0
|
| 461 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 462 |
# If we have .java files, compile them
|
| 463 |
if needs_compilation:
|
| 464 |
logger.info(f"Found {len(java_files)} Java source files, compiling...")
|
| 465 |
-
|
|
|
|
|
|
|
|
|
|
| 466 |
compile_process = await asyncio.create_subprocess_exec(
|
| 467 |
-
|
| 468 |
-
*[str(f) for f in java_files],
|
| 469 |
cwd=workspace,
|
| 470 |
stdout=asyncio.subprocess.PIPE,
|
| 471 |
stderr=asyncio.subprocess.PIPE,
|
| 472 |
)
|
| 473 |
-
|
| 474 |
stdout, stderr = await compile_process.communicate()
|
| 475 |
-
|
| 476 |
if compile_process.returncode != 0:
|
| 477 |
return ExecutionResult(
|
| 478 |
success=False,
|
|
@@ -481,7 +498,7 @@ class CodeExecutor:
|
|
| 481 |
execution_time=0,
|
| 482 |
exit_code=compile_process.returncode,
|
| 483 |
)
|
| 484 |
-
|
| 485 |
logger.info("Java compilation successful")
|
| 486 |
else:
|
| 487 |
# Check if we have .class files for the main files
|
|
@@ -491,10 +508,10 @@ class CodeExecutor:
|
|
| 491 |
class_file_path = os.path.join(workspace, main_file)
|
| 492 |
else:
|
| 493 |
class_file_path = os.path.join(workspace, f"{main_file}.class")
|
| 494 |
-
|
| 495 |
if not os.path.exists(class_file_path):
|
| 496 |
class_files_missing.append(main_file)
|
| 497 |
-
|
| 498 |
if class_files_missing:
|
| 499 |
return ExecutionResult(
|
| 500 |
success=False,
|
|
@@ -503,9 +520,9 @@ class CodeExecutor:
|
|
| 503 |
execution_time=0,
|
| 504 |
exit_code=-1,
|
| 505 |
)
|
| 506 |
-
|
| 507 |
logger.info("Using existing .class files, skipping compilation")
|
| 508 |
-
|
| 509 |
# Execute main files
|
| 510 |
results = []
|
| 511 |
for main_file in main_files:
|
|
@@ -516,7 +533,7 @@ class CodeExecutor:
|
|
| 516 |
class_name = main_file.replace(".java", "")
|
| 517 |
else:
|
| 518 |
class_name = main_file
|
| 519 |
-
|
| 520 |
# Verify the .class file exists
|
| 521 |
class_file_path = os.path.join(workspace, f"{class_name}.class")
|
| 522 |
if not os.path.exists(class_file_path):
|
|
@@ -530,16 +547,19 @@ class CodeExecutor:
|
|
| 530 |
)
|
| 531 |
)
|
| 532 |
continue
|
| 533 |
-
|
| 534 |
try:
|
| 535 |
start_time = asyncio.get_event_loop().time()
|
| 536 |
-
|
|
|
|
|
|
|
|
|
|
| 537 |
stdout, stderr, returncode = await self._execute_with_input(
|
| 538 |
-
|
| 539 |
)
|
| 540 |
-
|
| 541 |
execution_time = asyncio.get_event_loop().time() - start_time
|
| 542 |
-
|
| 543 |
results.append(
|
| 544 |
ExecutionResult(
|
| 545 |
success=returncode == 0,
|
|
@@ -549,7 +569,7 @@ class CodeExecutor:
|
|
| 549 |
exit_code=returncode,
|
| 550 |
)
|
| 551 |
)
|
| 552 |
-
|
| 553 |
except asyncio.TimeoutError:
|
| 554 |
results.append(
|
| 555 |
ExecutionResult(
|
|
@@ -571,7 +591,7 @@ class CodeExecutor:
|
|
| 571 |
error=str(e),
|
| 572 |
)
|
| 573 |
)
|
| 574 |
-
|
| 575 |
return self._combine_results(results, main_files)
|
| 576 |
|
| 577 |
async def _execute_c_cpp(
|
|
|
|
| 447 |
|
| 448 |
return self._combine_results(results, main_files)
|
| 449 |
|
| 450 |
+
# Thay thế method _execute_java trong CodeExecutor class
|
| 451 |
+
|
| 452 |
async def _execute_java(
|
| 453 |
self,
|
| 454 |
main_files: List[str],
|
| 455 |
workspace: str,
|
| 456 |
input_data: Optional[List[str]] = None,
|
| 457 |
) -> ExecutionResult:
|
| 458 |
+
"""Compile and execute Java code with input support and memory optimization"""
|
| 459 |
+
|
| 460 |
# Check if we have .java files to compile
|
| 461 |
java_files = list(Path(workspace).glob("*.java"))
|
| 462 |
needs_compilation = len(java_files) > 0
|
| 463 |
+
|
| 464 |
+
# JVM options for container environment
|
| 465 |
+
jvm_opts = [
|
| 466 |
+
"-Xms16m", # Initial heap size
|
| 467 |
+
"-Xmx128m", # Maximum heap size
|
| 468 |
+
"-XX:ReservedCodeCacheSize=16m", # Code cache size
|
| 469 |
+
"-XX:InitialCodeCacheSize=2m", # Initial code cache
|
| 470 |
+
"-XX:+UseSerialGC", # Simple GC for small apps
|
| 471 |
+
"-XX:+TieredCompilation", # Enable tiered compilation
|
| 472 |
+
"-XX:TieredStopAtLevel=1", # Stop at level 1 (faster startup)
|
| 473 |
+
"-XX:+UseStringDeduplication", # Save memory on strings
|
| 474 |
+
"-XX:MaxRAMPercentage=10.0", # Limit RAM usage to 10% of container
|
| 475 |
+
]
|
| 476 |
+
|
| 477 |
# If we have .java files, compile them
|
| 478 |
if needs_compilation:
|
| 479 |
logger.info(f"Found {len(java_files)} Java source files, compiling...")
|
| 480 |
+
|
| 481 |
+
# Compile with memory-optimized javac
|
| 482 |
+
compile_cmd = ["javac", "-J-Xmx64m"] + [str(f) for f in java_files]
|
| 483 |
+
|
| 484 |
compile_process = await asyncio.create_subprocess_exec(
|
| 485 |
+
*compile_cmd,
|
|
|
|
| 486 |
cwd=workspace,
|
| 487 |
stdout=asyncio.subprocess.PIPE,
|
| 488 |
stderr=asyncio.subprocess.PIPE,
|
| 489 |
)
|
| 490 |
+
|
| 491 |
stdout, stderr = await compile_process.communicate()
|
| 492 |
+
|
| 493 |
if compile_process.returncode != 0:
|
| 494 |
return ExecutionResult(
|
| 495 |
success=False,
|
|
|
|
| 498 |
execution_time=0,
|
| 499 |
exit_code=compile_process.returncode,
|
| 500 |
)
|
| 501 |
+
|
| 502 |
logger.info("Java compilation successful")
|
| 503 |
else:
|
| 504 |
# Check if we have .class files for the main files
|
|
|
|
| 508 |
class_file_path = os.path.join(workspace, main_file)
|
| 509 |
else:
|
| 510 |
class_file_path = os.path.join(workspace, f"{main_file}.class")
|
| 511 |
+
|
| 512 |
if not os.path.exists(class_file_path):
|
| 513 |
class_files_missing.append(main_file)
|
| 514 |
+
|
| 515 |
if class_files_missing:
|
| 516 |
return ExecutionResult(
|
| 517 |
success=False,
|
|
|
|
| 520 |
execution_time=0,
|
| 521 |
exit_code=-1,
|
| 522 |
)
|
| 523 |
+
|
| 524 |
logger.info("Using existing .class files, skipping compilation")
|
| 525 |
+
|
| 526 |
# Execute main files
|
| 527 |
results = []
|
| 528 |
for main_file in main_files:
|
|
|
|
| 533 |
class_name = main_file.replace(".java", "")
|
| 534 |
else:
|
| 535 |
class_name = main_file
|
| 536 |
+
|
| 537 |
# Verify the .class file exists
|
| 538 |
class_file_path = os.path.join(workspace, f"{class_name}.class")
|
| 539 |
if not os.path.exists(class_file_path):
|
|
|
|
| 547 |
)
|
| 548 |
)
|
| 549 |
continue
|
| 550 |
+
|
| 551 |
try:
|
| 552 |
start_time = asyncio.get_event_loop().time()
|
| 553 |
+
|
| 554 |
+
# Build java command with memory optimization
|
| 555 |
+
java_cmd = ["java"] + jvm_opts + [class_name]
|
| 556 |
+
|
| 557 |
stdout, stderr, returncode = await self._execute_with_input(
|
| 558 |
+
java_cmd, workspace, input_data
|
| 559 |
)
|
| 560 |
+
|
| 561 |
execution_time = asyncio.get_event_loop().time() - start_time
|
| 562 |
+
|
| 563 |
results.append(
|
| 564 |
ExecutionResult(
|
| 565 |
success=returncode == 0,
|
|
|
|
| 569 |
exit_code=returncode,
|
| 570 |
)
|
| 571 |
)
|
| 572 |
+
|
| 573 |
except asyncio.TimeoutError:
|
| 574 |
results.append(
|
| 575 |
ExecutionResult(
|
|
|
|
| 591 |
error=str(e),
|
| 592 |
)
|
| 593 |
)
|
| 594 |
+
|
| 595 |
return self._combine_results(results, main_files)
|
| 596 |
|
| 597 |
async def _execute_c_cpp(
|