fix kotlin
All checks were successful
Build and Push Docker Images / build (src/LiquidCode.Tester.Gateway/Dockerfile, git.nullptr.top/liquidcode/liquidcode-tester-gateway-roman, gateway) (push) Successful in 47s
Build and Push Docker Images / build (src/LiquidCode.Tester.Worker/Dockerfile, git.nullptr.top/liquidcode/liquidcode-tester-worker-roman, worker) (push) Successful in 1m4s

This commit is contained in:
prixod
2025-12-01 22:47:30 +04:00
parent f5cb2c8e2e
commit 7a1f22eb8e

View File

@@ -15,7 +15,7 @@ public class KotlinCompilationServiceIsolate : ICompilationService
private readonly IsolateBoxPool _boxPool; private readonly IsolateBoxPool _boxPool;
private const int CompilationTimeLimitSeconds = 30; private const int CompilationTimeLimitSeconds = 30;
private const int CompilationMemoryLimitMb = 512; private const int CompilationMemoryLimitMb = 1024; // Kotlin uses JVM, needs more memory
public KotlinCompilationServiceIsolate( public KotlinCompilationServiceIsolate(
ILogger<KotlinCompilationServiceIsolate> logger, ILogger<KotlinCompilationServiceIsolate> logger,
@@ -39,7 +39,21 @@ public class KotlinCompilationServiceIsolate : ICompilationService
try try
{ {
await File.WriteAllTextAsync(sourceFilePath, sourceCode); // Normalize line endings
var normalizedSourceCode = sourceCode
.Replace("\\r\\n", "\n") // Handle escaped \r\n (literal text "\\r\\n")
.Replace("\\n", "\n") // Handle escaped \n (literal text "\\n")
.Replace("\\r", "\n") // Handle escaped \r (literal text "\\r")
.Replace("\r\n", "\n") // Handle actual Windows line endings
.Replace("\r", "\n"); // Handle actual Mac line endings
_logger.LogDebug("Source code length: {Length}, normalized length: {NormalizedLength}, line count: {LineCount}",
sourceCode.Length, normalizedSourceCode.Length, normalizedSourceCode.Split('\n').Length);
_logger.LogDebug("First 200 chars of source: {Preview}",
normalizedSourceCode.Length > 200 ? normalizedSourceCode.Substring(0, 200) : normalizedSourceCode);
await File.WriteAllTextAsync(sourceFilePath, normalizedSourceCode);
return await CompileFileInIsolateAsync(sourceFilePath, jarFilePath, version); return await CompileFileInIsolateAsync(sourceFilePath, jarFilePath, version);
} }
catch (Exception ex) catch (Exception ex)
@@ -89,6 +103,7 @@ public class KotlinCompilationServiceIsolate : ICompilationService
arguments.Add($"/box/{jarFileName}"); arguments.Add($"/box/{jarFileName}");
var stderrFilePath = Path.Combine(boxDir, "compile_stderr.txt"); var stderrFilePath = Path.Combine(boxDir, "compile_stderr.txt");
var stdoutFilePath = Path.Combine(boxDir, "compile_stdout.txt");
var isolateResult = await _isolateService.RunAsync(new IsolateRunOptions var isolateResult = await _isolateService.RunAsync(new IsolateRunOptions
{ {
@@ -98,9 +113,10 @@ public class KotlinCompilationServiceIsolate : ICompilationService
TimeLimitSeconds = CompilationTimeLimitSeconds, TimeLimitSeconds = CompilationTimeLimitSeconds,
WallTimeLimitSeconds = CompilationTimeLimitSeconds * 2, WallTimeLimitSeconds = CompilationTimeLimitSeconds * 2,
MemoryLimitKb = CompilationMemoryLimitMb * 1024, MemoryLimitKb = CompilationMemoryLimitMb * 1024,
StackLimitKb = 256 * 1024, StackLimitKb = 128 * 1024, // 128MB stack per process
ProcessLimit = 10, ProcessLimit = 64, // Kotlin uses JVM, needs many threads/processes
EnableNetwork = false, EnableNetwork = false,
StdoutFile = stdoutFilePath,
StderrFile = stderrFilePath, StderrFile = stderrFilePath,
WorkingDirectory = "/box", WorkingDirectory = "/box",
DirectoryBindings = new List<DirectoryBinding> DirectoryBindings = new List<DirectoryBinding>
@@ -120,13 +136,34 @@ public class KotlinCompilationServiceIsolate : ICompilationService
}); });
var compilerOutput = string.Empty; var compilerOutput = string.Empty;
// Read stdout (kotlinc may output errors there)
if (File.Exists(stdoutFilePath))
{
var stdoutContent = await File.ReadAllTextAsync(stdoutFilePath);
if (!string.IsNullOrWhiteSpace(stdoutContent))
{
compilerOutput = stdoutContent;
}
}
// Read stderr
if (File.Exists(stderrFilePath)) if (File.Exists(stderrFilePath))
{ {
compilerOutput = await File.ReadAllTextAsync(stderrFilePath); var stderrContent = await File.ReadAllTextAsync(stderrFilePath);
if (!string.IsNullOrWhiteSpace(stderrContent))
{
compilerOutput = string.IsNullOrEmpty(compilerOutput)
? stderrContent
: $"{compilerOutput}\n{stderrContent}";
}
} }
if (!string.IsNullOrEmpty(isolateResult.ErrorOutput)) if (!string.IsNullOrEmpty(isolateResult.ErrorOutput))
{ {
compilerOutput = $"{compilerOutput}\n{isolateResult.ErrorOutput}".Trim(); compilerOutput = string.IsNullOrEmpty(compilerOutput)
? isolateResult.ErrorOutput
: $"{compilerOutput}\n{isolateResult.ErrorOutput}";
} }
if (isolateResult.TimeLimitExceeded) if (isolateResult.TimeLimitExceeded)