SoarGroup / Soar

Soar, a general cognitive architecture for systems that exhibit intelligent behavior.
http://soar.eecs.umich.edu
Other
322 stars 70 forks source link

creating agent with same name as previously destroyed agent breaks traces #436

Closed garfieldnate closed 1 month ago

garfieldnate commented 3 months ago

If you activate the debugger, create an agent with a particular name, then destroy that agent (which closes the debugger window for it), then create a new agent with the same name, the debugger will not show any traces in the window. Return values for commands are still printed, and the various other panes are still updated, but I guess something goes wrong with print event registration because no matter what level you set watch to, you never see traces in that agent window. Any other existing agent windows still show traces correctly.

Here's an MBE:

#!/usr/bin/env python3
import time

from Python_sml_ClientInterface import Kernel, smlEVENT_PRINT

def print_callback(id, userData, agent, message):
    print(f"Callback: {message}")

kernel = Kernel.CreateKernelInNewThread()

agent1 = agent = kernel.CreateAgent("Soar1")
printcallbackid1 = agent1.RegisterForPrintEvent(
    smlEVENT_PRINT, print_callback, None
)

kernel.ExecuteCommandLine("watch 1", "Soar1")

agent1.SpawnDebugger()
# watch for the debugger to open
time.sleep(2)

agent2 = kernel.CreateAgent("Soar2")
printcallbackid2 = agent2.RegisterForPrintEvent(
    smlEVENT_PRINT, print_callback, None
)
# watch for second debugger window to open
time.sleep(2)

kernel.DestroyAgent(agent2)
# watch for second debugger window to close
time.sleep(1)

agent2 = kernel.CreateAgent("Soar2")
printcallbackid3 = agent2.RegisterForPrintEvent(
    smlEVENT_PRINT, print_callback, None
)
# watch for second debugger window to open
time.sleep(1)

# stepping in Soar2 will show traces in the Soar1 window
for i in range(0, 10):
    kernel.ExecuteCommandLine("d", "Soar2")
    time.sleep(0.5)

# BUG: stepping in Soar1 will *not* show traces in the Soar2 window
# OK: however, all print events are correctly sent to print_callback, so you will see them in stdout
for i in range(0, 10):
    kernel.ExecuteCommandLine("d", "Soar1")
    time.sleep(0.5)

# sleep forever so you can test the debuggers manually here if you like
time.sleep(20000)

Run with `PYTHONPATH=$SOAR_HOME python3

garfieldnate commented 2 months ago

Note: check if fixing this also repairs the input/output link display in the upper right corner.

garfieldnate commented 1 month ago

Does not occur if you use the debugger to create and destroy the agents, which makes testing it more difficult.

garfieldnate commented 1 month ago

To debug the debugger in this case, a slightly different approach is needed. First run this:

#!/usr/bin/env python3
import time

from Python_sml_ClientInterface import Kernel, smlEVENT_PRINT

def print_callback(id, userData, agent, message):
    print(f"Callback: {message}")

kernel = Kernel.CreateKernelInNewThread()

agent1 = agent = kernel.CreateAgent("Soar1")
printcallbackid1 = agent1.RegisterForPrintEvent(
    smlEVENT_PRINT, print_callback, None
)

print("Creating Soar1 agent...")
kernel.ExecuteCommandLine("watch 1", "Soar1")

input("Connect the debugger to the kernel at localhost:12121, then press Enter to continue...")

print("Creating Soar2 agent...")
agent2 = kernel.CreateAgent("Soar2")
printcallbackid2 = agent2.RegisterForPrintEvent(
    smlEVENT_PRINT, print_callback, None
)

input("Press enter to destroy Soar2 agent...")
kernel.DestroyAgent(agent2)

input("Press enter to create another Soar2 agent...")
agent2 = kernel.CreateAgent("Soar2")
printcallbackid3 = agent2.RegisterForPrintEvent(
    smlEVENT_PRINT, print_callback, None
)

# stepping in Soar2 will show traces in the Soar1 window
input("Press enter to start stepping in Soar2, which will show traces in the Soar1 window")
for i in range(0, 10):
    kernel.ExecuteCommandLine("d", "Soar2")
    time.sleep(0.5)

# BUG: stepping in Soar1 will *not* show traces in the Soar2 window
# OK: however, all print events are correctly sent to print_callback, so you will see them in stdout
input("Press enter to demonstrate the BUG: Stepping in Soar1 will *not* show traces in the Soar2 window")
for i in range(0, 10):
    kernel.ExecuteCommandLine("d", "Soar1")
    time.sleep(0.5)

print("OK: However, all print events are correctly sent to print_callback, so you should see them above")

# sleep forever so you can test the debuggers manually here if you like
time.sleep(20000)

Then start the debugger process and connect it to the remote kernel at localhost:12121 when prompted. Then the script will continue and the issue will be reproduced.

garfieldnate commented 1 month ago

It appears that this was fixed via 23a90cd17fb53c561eca384418c0f25be591e5a7.