ABAO77 commited on
Commit
072178c
·
verified ·
1 Parent(s): 0f90aa0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +137 -78
app.py CHANGED
@@ -114,18 +114,35 @@ if [ "$AVAILABLE_MEM" -lt 20 ]; then
114
  exit 1
115
  fi
116
 
117
- # Calculate heap size (30% of available, min 4MB, max 12MB)
118
- HEAP_SIZE=$((AVAILABLE_MEM * 30 / 100))
119
  if [ "$HEAP_SIZE" -lt 4 ]; then
120
  HEAP_SIZE=4
121
- elif [ "$HEAP_SIZE" -gt 12 ]; then
122
- HEAP_SIZE=12
123
  fi
124
 
125
- echo "Using ${HEAP_SIZE}MB heap (${AVAILABLE_MEM}MB available)" >&2
 
 
 
 
126
 
127
- # Execute Java with calculated settings
128
- exec java -Xms1m -Xmx${HEAP_SIZE}m -Djava.awt.headless=true "$@"
 
 
 
 
 
 
 
 
 
 
 
 
 
129
  """
130
 
131
  wrapper_path = os.path.join(workspace, "java_wrapper.sh")
@@ -583,91 +600,133 @@ exec java -Xms1m -Xmx${HEAP_SIZE}m -Djava.awt.headless=true "$@"
583
  workspace: str,
584
  input_data: Optional[List[str]] = None,
585
  ) -> ExecutionResult:
586
- """Execute Java using a memory-aware wrapper script"""
587
 
588
- try:
589
- # Create wrapper script
590
- wrapper_path = await self._create_java_wrapper(workspace)
 
 
 
 
 
 
 
591
 
592
- results = []
593
- for main_file in main_files:
594
- # Determine class name
595
- if main_file.endswith(".class"):
596
- class_name = main_file.replace(".class", "")
597
- elif main_file.endswith(".java"):
598
- class_name = main_file.replace(".java", "")
599
  else:
600
- class_name = main_file
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
 
602
- # Verify the .class file exists
603
- class_file_path = os.path.join(workspace, f"{class_name}.class")
604
- if not os.path.exists(class_file_path):
605
- results.append(
606
- ExecutionResult(
607
- success=False,
608
- stdout="",
609
- stderr=f"Class file not found: {class_name}.class",
610
- execution_time=0,
611
- exit_code=-1,
612
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
613
  )
614
- continue
 
615
 
616
- try:
617
- start_time = asyncio.get_event_loop().time()
618
 
619
- # Use wrapper script instead of direct java
620
- java_cmd = [wrapper_path, class_name]
621
-
622
- stdout, stderr, returncode = await self._execute_with_input(
623
- java_cmd, workspace, input_data
624
- )
 
 
 
 
 
625
 
626
- execution_time = asyncio.get_event_loop().time() - start_time
627
 
628
- results.append(
629
- ExecutionResult(
630
- success=returncode == 0,
631
- stdout=stdout.decode("utf-8", errors="replace"),
632
- stderr=stderr.decode("utf-8", errors="replace"),
633
- execution_time=execution_time,
634
- exit_code=returncode,
635
- )
636
  )
 
637
 
638
- except asyncio.TimeoutError:
639
- results.append(
640
- ExecutionResult(
641
- success=False,
642
- stdout="",
643
- stderr="Execution timeout exceeded",
644
- execution_time=MAX_EXECUTION_TIME,
645
- exit_code=-1,
646
- )
647
  )
648
- except Exception as e:
649
- results.append(
650
- ExecutionResult(
651
- success=False,
652
- stdout="",
653
- stderr=str(e),
654
- execution_time=0,
655
- exit_code=-1,
656
- error=str(e),
657
- )
658
  )
 
659
 
660
- return self._combine_results(results, main_files)
661
-
662
- except Exception as e:
663
- return ExecutionResult(
664
- success=False,
665
- stdout="",
666
- stderr=f"Wrapper execution failed: {str(e)}",
667
- execution_time=0,
668
- exit_code=-1,
669
- error=str(e),
670
- )
671
 
672
  async def _execute_c_cpp(
673
  self,
 
114
  exit 1
115
  fi
116
 
117
+ # Calculate heap size (20% of available, min 4MB, max 8MB)
118
+ HEAP_SIZE=$((AVAILABLE_MEM * 20 / 100))
119
  if [ "$HEAP_SIZE" -lt 4 ]; then
120
  HEAP_SIZE=4
121
+ elif [ "$HEAP_SIZE" -gt 8 ]; then
122
+ HEAP_SIZE=8
123
  fi
124
 
125
+ # Calculate code cache (much smaller)
126
+ CODE_CACHE_SIZE=$((HEAP_SIZE / 2))
127
+ if [ "$CODE_CACHE_SIZE" -lt 2 ]; then
128
+ CODE_CACHE_SIZE=2
129
+ fi
130
 
131
+ echo "Using ${HEAP_SIZE}MB heap, ${CODE_CACHE_SIZE}MB code cache (${AVAILABLE_MEM}MB available)" >&2
132
+
133
+ # Execute Java with all memory limits
134
+ exec java \\
135
+ -Xms1m \\
136
+ -Xmx${HEAP_SIZE}m \\
137
+ -XX:ReservedCodeCacheSize=${CODE_CACHE_SIZE}m \\
138
+ -XX:InitialCodeCacheSize=1m \\
139
+ -XX:+UseSerialGC \\
140
+ -XX:MaxMetaspaceSize=8m \\
141
+ -XX:CompressedClassSpaceSize=4m \\
142
+ -Xss128k \\
143
+ -XX:-TieredCompilation \\
144
+ -Djava.awt.headless=true \\
145
+ "$@"
146
  """
147
 
148
  wrapper_path = os.path.join(workspace, "java_wrapper.sh")
 
600
  workspace: str,
601
  input_data: Optional[List[str]] = None,
602
  ) -> ExecutionResult:
603
+ """Execute Java using a memory-aware wrapper script with fallback"""
604
 
605
+ # Try wrapper first, then fallback to minimal direct execution
606
+ approaches = [
607
+ ("wrapper", None),
608
+ ("minimal", ["-Xms1m", "-Xmx8m", "-Djava.awt.headless=true"]),
609
+ ("ultra_minimal", ["-Xms1m", "-Xmx4m", "-Djava.awt.headless=true"]),
610
+ ("no_limits", ["-Djava.awt.headless=true"])
611
+ ]
612
+
613
+ for approach_name, jvm_opts in approaches:
614
+ logger.info(f"Trying Java execution approach: {approach_name}")
615
 
616
+ try:
617
+ if approach_name == "wrapper":
618
+ # Create and use wrapper script
619
+ wrapper_path = await self._create_java_wrapper(workspace)
620
+ result = await self._try_java_direct(main_files, workspace, input_data, wrapper_cmd=wrapper_path)
 
 
621
  else:
622
+ # Use direct java with specific JVM options
623
+ result = await self._try_java_direct(main_files, workspace, input_data, jvm_opts=jvm_opts)
624
+
625
+ # If successful or not a memory error, return result
626
+ if result.success or "Could not reserve" not in result.stderr:
627
+ logger.info(f"Java execution successful with approach: {approach_name}")
628
+ return result
629
+ else:
630
+ logger.warning(f"Approach {approach_name} failed with memory error, trying next...")
631
+
632
+ except Exception as e:
633
+ logger.warning(f"Approach {approach_name} failed with exception: {e}")
634
+ continue
635
+
636
+ # If all approaches fail
637
+ return ExecutionResult(
638
+ success=False,
639
+ stdout="",
640
+ stderr="Java execution failed with all memory configurations. Container memory too limited for JVM.",
641
+ execution_time=0,
642
+ exit_code=-1,
643
+ error="All JVM memory configurations failed"
644
+ )
645
 
646
+ async def _try_java_direct(
647
+ self,
648
+ main_files: List[str],
649
+ workspace: str,
650
+ input_data: Optional[List[str]],
651
+ wrapper_cmd: Optional[str] = None,
652
+ jvm_opts: Optional[List[str]] = None
653
+ ) -> ExecutionResult:
654
+ """Try Java execution with specific configuration"""
655
+
656
+ results = []
657
+ for main_file in main_files:
658
+ # Determine class name
659
+ if main_file.endswith(".class"):
660
+ class_name = main_file.replace(".class", "")
661
+ elif main_file.endswith(".java"):
662
+ class_name = main_file.replace(".java", "")
663
+ else:
664
+ class_name = main_file
665
+
666
+ # Verify the .class file exists
667
+ class_file_path = os.path.join(workspace, f"{class_name}.class")
668
+ if not os.path.exists(class_file_path):
669
+ results.append(
670
+ ExecutionResult(
671
+ success=False,
672
+ stdout="",
673
+ stderr=f"Class file not found: {class_name}.class",
674
+ execution_time=0,
675
+ exit_code=-1,
676
  )
677
+ )
678
+ continue
679
 
680
+ try:
681
+ start_time = asyncio.get_event_loop().time()
682
 
683
+ # Build command
684
+ if wrapper_cmd:
685
+ java_cmd = [wrapper_cmd, class_name]
686
+ elif jvm_opts:
687
+ java_cmd = ["java"] + jvm_opts + [class_name]
688
+ else:
689
+ java_cmd = ["java", class_name]
690
+
691
+ stdout, stderr, returncode = await self._execute_with_input(
692
+ java_cmd, workspace, input_data
693
+ )
694
 
695
+ execution_time = asyncio.get_event_loop().time() - start_time
696
 
697
+ results.append(
698
+ ExecutionResult(
699
+ success=returncode == 0,
700
+ stdout=stdout.decode("utf-8", errors="replace"),
701
+ stderr=stderr.decode("utf-8", errors="replace"),
702
+ execution_time=execution_time,
703
+ exit_code=returncode,
 
704
  )
705
+ )
706
 
707
+ except asyncio.TimeoutError:
708
+ results.append(
709
+ ExecutionResult(
710
+ success=False,
711
+ stdout="",
712
+ stderr="Execution timeout exceeded",
713
+ execution_time=MAX_EXECUTION_TIME,
714
+ exit_code=-1,
 
715
  )
716
+ )
717
+ except Exception as e:
718
+ results.append(
719
+ ExecutionResult(
720
+ success=False,
721
+ stdout="",
722
+ stderr=str(e),
723
+ execution_time=0,
724
+ exit_code=-1,
725
+ error=str(e),
726
  )
727
+ )
728
 
729
+ return self._combine_results(results, main_files)
 
 
 
 
 
 
 
 
 
 
730
 
731
  async def _execute_c_cpp(
732
  self,