Skip to content

Commit ef3b4ff

Browse files
authored
Merge pull request #1218 from iceljc/bugfix/refine-code-lock
add py logging
2 parents dd6697a + 7139a2e commit ef3b4ff

File tree

2 files changed

+64
-58
lines changed

2 files changed

+64
-58
lines changed

src/Plugins/BotSharp.Plugin.PythonInterpreter/PythonInterpreterPlugin.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ public void Configure(IApplicationBuilder app)
4040
Runtime.PythonDLL = pyLoc;
4141
PythonEngine.Initialize();
4242
_pyState = PythonEngine.BeginAllowThreads();
43+
PythonEngine.DebugGIL = true;
4344

4445
lifetime.ApplicationStopping.Register(() => {
4546
try

src/Plugins/BotSharp.Plugin.PythonInterpreter/Services/PyCodeInterpreter.cs

Lines changed: 63 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -160,79 +160,84 @@ private CodeInterpretResponse CoreRunScript(string codeScript, CodeInterpretOpti
160160
{
161161
Thread.Sleep(100);
162162

163-
// For observation purpose
164-
var requestId = Guid.NewGuid();
165-
_logger.LogWarning($"Before acquiring Py.GIL for request {requestId}");
163+
_logger.LogWarning($"Before acquiring Py.GIL (Python engine initialized: {PythonEngine.IsInitialized}). Thread {Thread.CurrentThread.ManagedThreadId}.");
166164

167-
using (Py.GIL())
168-
{
169-
_logger.LogWarning($"After acquiring Py.GIL for request {requestId}");
165+
var gil = Py.GIL();
170166

171-
// Import necessary Python modules
172-
dynamic sys = Py.Import("sys");
173-
dynamic io = Py.Import("io");
167+
_logger.LogWarning($"After acquiring Py.GIL ({gil != null}). Thread {Thread.CurrentThread.ManagedThreadId}.");
174168

175-
try
169+
// Import necessary Python modules
170+
dynamic sys = Py.Import("sys");
171+
dynamic io = Py.Import("io");
172+
173+
try
174+
{
175+
// Redirect standard output/error to capture it
176+
dynamic outIO = io.StringIO();
177+
dynamic errIO = io.StringIO();
178+
sys.stdout = outIO;
179+
sys.stderr = errIO;
180+
181+
// Set global items
182+
using var globals = new PyDict();
183+
if (codeScript.Contains("__main__") == true)
176184
{
177-
// Redirect standard output/error to capture it
178-
dynamic outIO = io.StringIO();
179-
dynamic errIO = io.StringIO();
180-
sys.stdout = outIO;
181-
sys.stderr = errIO;
182-
183-
// Set global items
184-
using var globals = new PyDict();
185-
if (codeScript.Contains("__main__") == true)
186-
{
187-
globals.SetItem("__name__", new PyString("__main__"));
188-
}
185+
globals.SetItem("__name__", new PyString("__main__"));
186+
}
189187

190-
// Set arguments
191-
var list = new PyList();
192-
if (options?.Arguments?.Any() == true)
193-
{
194-
list.Append(new PyString(options?.ScriptName ?? $"{Guid.NewGuid()}.py"));
188+
// Set arguments
189+
var list = new PyList();
190+
if (options?.Arguments?.Any() == true)
191+
{
192+
list.Append(new PyString(options?.ScriptName ?? $"{Guid.NewGuid()}.py"));
195193

196-
foreach (var arg in options!.Arguments)
194+
foreach (var arg in options!.Arguments)
195+
{
196+
if (!string.IsNullOrWhiteSpace(arg.Key) && !string.IsNullOrWhiteSpace(arg.Value))
197197
{
198-
if (!string.IsNullOrWhiteSpace(arg.Key) && !string.IsNullOrWhiteSpace(arg.Value))
199-
{
200-
list.Append(new PyString($"--{arg.Key}"));
201-
list.Append(new PyString($"{arg.Value}"));
202-
}
198+
list.Append(new PyString($"--{arg.Key}"));
199+
list.Append(new PyString($"{arg.Value}"));
203200
}
204201
}
205-
sys.argv = list;
202+
}
203+
sys.argv = list;
206204

207-
// Execute Python script
208-
PythonEngine.Exec(codeScript, globals);
205+
_logger.LogWarning($"Code script {options?.ScriptName} arguments: {string.Join("\r\n", options?.Arguments?.Select(x => x.ToString()) ?? [])}. Thread: {Thread.CurrentThread.ManagedThreadId}.");
209206

210-
_logger.LogWarning($"Complete {nameof(CoreRunScript)} in {Provider}: ${options?.ScriptName}");
207+
_logger.LogWarning($"Before executing code script {options?.ScriptName}. Thread: {Thread.CurrentThread.ManagedThreadId}.");
211208

212-
// Get result
213-
var stdout = outIO.getvalue()?.ToString() as string;
214-
var stderr = errIO.getvalue()?.ToString() as string;
209+
// Execute Python script
210+
PythonEngine.Exec(codeScript, globals);
215211

216-
return new CodeInterpretResponse
217-
{
218-
Result = stdout?.TrimEnd('\r', '\n') ?? string.Empty,
219-
Success = true
220-
};
221-
}
222-
catch (Exception ex)
223-
{
224-
_logger.LogError(ex, $"Error in {nameof(CoreRunScript)} in {Provider}.");
225-
return new() { ErrorMsg = ex.Message };
226-
}
227-
finally
212+
_logger.LogWarning($"After executing code script {options?.ScriptName}. Thread: {Thread.CurrentThread.ManagedThreadId}.");
213+
214+
// Get result
215+
var stdout = outIO.getvalue()?.ToString() as string;
216+
var stderr = errIO.getvalue()?.ToString() as string;
217+
218+
return new CodeInterpretResponse
228219
{
229-
// Restore the original stdout/stderr/argv
230-
sys.stdout = sys.__stdout__;
231-
sys.stderr = sys.__stderr__;
232-
sys.argv = new PyList();
233-
}
220+
Result = stdout?.TrimEnd('\r', '\n') ?? string.Empty,
221+
Success = true
222+
};
223+
}
224+
catch (Exception ex)
225+
{
226+
_logger.LogError(ex, $"Error in {nameof(CoreRunScript)} in {Provider}.");
227+
return new() { ErrorMsg = ex.Message };
228+
}
229+
finally
230+
{
231+
// Restore the original stdout/stderr/argv
232+
sys.stdout = sys.__stdout__;
233+
sys.stderr = sys.__stderr__;
234+
sys.argv = new PyList();
235+
236+
_logger.LogWarning($"Before disposing Py.GIL ({gil != null}). Thread {Thread.CurrentThread.ManagedThreadId}.");
237+
gil?.Dispose();
238+
_logger.LogWarning($"After disposing Py.GIL. Thread {Thread.CurrentThread.ManagedThreadId}.");
234239
}
235-
}, cancellationToken);
240+
}, cancellationToken, TaskCreationOptions.LongRunning, TaskScheduler.Default);
236241

237242
return execTask.WaitAsync(cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult();
238243
}

0 commit comments

Comments
 (0)