mirror of
https://github.com/logos-messaging/logos-messaging-nim.git
synced 2026-01-07 16:33:08 +00:00
Add additional checks for stopAnvil process
This commit is contained in:
parent
08f87c570a
commit
17cf587ce6
@ -479,6 +479,57 @@ proc getAnvilPath*(): string =
|
|||||||
anvilPath = joinPath(anvilPath, ".foundry/bin/anvil")
|
anvilPath = joinPath(anvilPath, ".foundry/bin/anvil")
|
||||||
return $anvilPath
|
return $anvilPath
|
||||||
|
|
||||||
|
proc checkRunningAnvilInstances*(): int =
|
||||||
|
## Returns the number of running Anvil processes
|
||||||
|
try:
|
||||||
|
when defined(windows):
|
||||||
|
let (output, exitCode) = execCmdEx(
|
||||||
|
"tasklist /FI \"IMAGENAME eq anvil.exe\" /FO CSV | find /C \"anvil.exe\""
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
let (output, exitCode) = execCmdEx("pgrep -c anvil 2>/dev/null || echo 0")
|
||||||
|
|
||||||
|
if exitCode == 0:
|
||||||
|
# Handle case where output might have multiple lines
|
||||||
|
let lines = output.strip().split('\n')
|
||||||
|
let countStr =
|
||||||
|
if lines.len > 0:
|
||||||
|
lines[0]
|
||||||
|
else:
|
||||||
|
"0"
|
||||||
|
let count = parseInt(countStr)
|
||||||
|
debug "Found running Anvil instances", count = count
|
||||||
|
return count
|
||||||
|
else:
|
||||||
|
debug "Failed to check running Anvil instances", exitCode = exitCode
|
||||||
|
return 0
|
||||||
|
except ValueError:
|
||||||
|
debug "Could not parse Anvil instance count"
|
||||||
|
return 0
|
||||||
|
except Exception:
|
||||||
|
debug "Error checking Anvil instances", error = getCurrentExceptionMsg()
|
||||||
|
return 0
|
||||||
|
|
||||||
|
proc isAnvilProcessRunning*(pid: int): bool =
|
||||||
|
## Checks if a specific PID is running an Anvil process
|
||||||
|
try:
|
||||||
|
when defined(windows):
|
||||||
|
let (output, exitCode) = execCmdEx(
|
||||||
|
fmt"tasklist /FI \" PID eq {pid} \ " /FI \"IMAGENAME eq anvil.exe\" /FO CSV"
|
||||||
|
)
|
||||||
|
result = exitCode == 0 and "anvil.exe" in output.toLower()
|
||||||
|
else:
|
||||||
|
let (output, exitCode) =
|
||||||
|
execCmdEx(fmt"ps -p {pid} -o comm= 2>/dev/null | grep -q anvil")
|
||||||
|
result = exitCode == 0
|
||||||
|
|
||||||
|
debug "Checking if PID is running Anvil", pid = pid, isRunning = result
|
||||||
|
return result
|
||||||
|
except Exception:
|
||||||
|
debug "Error checking if PID is Anvil process",
|
||||||
|
pid = pid, error = getCurrentExceptionMsg()
|
||||||
|
return false
|
||||||
|
|
||||||
# Runs Anvil daemon
|
# Runs Anvil daemon
|
||||||
proc runAnvil*(port: int = 8540, chainId: string = "1234"): Process =
|
proc runAnvil*(port: int = 8540, chainId: string = "1234"): Process =
|
||||||
# Passed options are
|
# Passed options are
|
||||||
@ -488,6 +539,11 @@ proc runAnvil*(port: int = 8540, chainId: string = "1234"): Process =
|
|||||||
# --chain-id Chain ID of the network.
|
# --chain-id Chain ID of the network.
|
||||||
# See anvil documentation https://book.getfoundry.sh/reference/anvil/ for more details
|
# See anvil documentation https://book.getfoundry.sh/reference/anvil/ for more details
|
||||||
try:
|
try:
|
||||||
|
# Check for existing Anvil instances before starting a new one
|
||||||
|
let runningInstances = checkRunningAnvilInstances()
|
||||||
|
debug "Checking for running Anvil instances before starting",
|
||||||
|
runningInstances = runningInstances
|
||||||
|
|
||||||
let anvilPath = getAnvilPath()
|
let anvilPath = getAnvilPath()
|
||||||
debug "Anvil path", anvilPath
|
debug "Anvil path", anvilPath
|
||||||
let runAnvil = startProcess(
|
let runAnvil = startProcess(
|
||||||
@ -495,30 +551,45 @@ proc runAnvil*(port: int = 8540, chainId: string = "1234"): Process =
|
|||||||
args = [
|
args = [
|
||||||
"--port",
|
"--port",
|
||||||
$port,
|
$port,
|
||||||
"--accounts",
|
|
||||||
"25",
|
|
||||||
"--gas-limit",
|
"--gas-limit",
|
||||||
"300000000000000",
|
"300000000000000",
|
||||||
"--balance",
|
"--balance",
|
||||||
"1000000000",
|
"1000000000",
|
||||||
"--chain-id",
|
"--chain-id",
|
||||||
$chainId
|
$chainId,
|
||||||
],
|
],
|
||||||
options = {poUsePath},
|
options = {poUsePath, poStdErrToStdOut},
|
||||||
)
|
)
|
||||||
let anvilPID = runAnvil.processID
|
let anvilPID = runAnvil.processID
|
||||||
|
|
||||||
|
# Add timeout mechanism
|
||||||
|
let startTime = Moment.now()
|
||||||
|
let timeoutDuration = 60.seconds # 60 second timeout
|
||||||
|
|
||||||
# We read stdout from Anvil to see when daemon is ready
|
# We read stdout from Anvil to see when daemon is ready
|
||||||
var anvilStartLog: string
|
var anvilStartLog: string
|
||||||
var cmdline: string
|
var cmdline: string
|
||||||
while true:
|
while (Moment.now() - startTime) < timeoutDuration:
|
||||||
|
if not runAnvil.running:
|
||||||
|
error "Anvil process died unexpectedly"
|
||||||
|
raise newException(IOError, "Anvil process failed to start")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if runAnvil.outputstream.readLine(cmdline):
|
if runAnvil.outputstream.readLine(cmdline):
|
||||||
anvilStartLog.add(cmdline)
|
anvilStartLog.add(cmdline)
|
||||||
if cmdline.contains("Listening on 127.0.0.1:" & $port):
|
if cmdline.contains("Listening on 127.0.0.1:" & $port):
|
||||||
break
|
break
|
||||||
|
else:
|
||||||
|
sleep(100)
|
||||||
except Exception, CatchableError:
|
except Exception, CatchableError:
|
||||||
break
|
break
|
||||||
|
|
||||||
|
# Check if we timed out
|
||||||
|
if (Moment.now() - startTime) >= timeoutDuration:
|
||||||
|
kill(runAnvil)
|
||||||
|
error "Anvil startup timed out after 60 seconds"
|
||||||
|
raise newException(IOError, "Anvil startup timed out")
|
||||||
|
|
||||||
debug "Anvil daemon is running and ready", pid = anvilPID, startLog = anvilStartLog
|
debug "Anvil daemon is running and ready", pid = anvilPID, startLog = anvilStartLog
|
||||||
return runAnvil
|
return runAnvil
|
||||||
except: # TODO: Fix "BareExcept" warning
|
except: # TODO: Fix "BareExcept" warning
|
||||||
@ -527,13 +598,40 @@ proc runAnvil*(port: int = 8540, chainId: string = "1234"): Process =
|
|||||||
# Stops Anvil daemon
|
# Stops Anvil daemon
|
||||||
proc stopAnvil*(runAnvil: Process) {.used.} =
|
proc stopAnvil*(runAnvil: Process) {.used.} =
|
||||||
let anvilPID = runAnvil.processID
|
let anvilPID = runAnvil.processID
|
||||||
# We wait the daemon to exit
|
|
||||||
|
if not isAnvilProcessRunning(anvilPID):
|
||||||
|
return
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# We terminate Anvil daemon by sending a SIGTERM signal to the runAnvil PID to trigger RPC server termination and clean-up
|
# Close Process object to release resources
|
||||||
kill(runAnvil)
|
close(runAnvil)
|
||||||
debug "Sent SIGTERM to Anvil", anvilPID = anvilPID
|
sleep(500)
|
||||||
except:
|
|
||||||
error "Anvil daemon termination failed: ", err = getCurrentExceptionMsg()
|
if isAnvilProcessRunning(anvilPID):
|
||||||
|
when not defined(windows):
|
||||||
|
# Try SIGTERM first
|
||||||
|
discard execCmdEx(fmt"kill -TERM {anvilPID}")
|
||||||
|
sleep(1000)
|
||||||
|
|
||||||
|
if isAnvilProcessRunning(anvilPID):
|
||||||
|
# Try SIGKILL
|
||||||
|
discard execCmdEx(fmt"kill -9 {anvilPID}")
|
||||||
|
sleep(1000)
|
||||||
|
|
||||||
|
if isAnvilProcessRunning(anvilPID):
|
||||||
|
# Check if it's a zombie process and reap it
|
||||||
|
let (psOutput, _) = execCmdEx(fmt"ps -p {anvilPID} -o stat= 2>/dev/null")
|
||||||
|
if "Z" in psOutput:
|
||||||
|
try:
|
||||||
|
discard waitForExit(runAnvil)
|
||||||
|
except:
|
||||||
|
discard # Process cleanup will happen when parent exits
|
||||||
|
else:
|
||||||
|
discard execCmdEx(fmt"taskkill /F /PID {anvilPID}")
|
||||||
|
|
||||||
|
debug "Anvil daemon stopped", anvilPID = anvilPID
|
||||||
|
except Exception as e:
|
||||||
|
debug "Error stopping Anvil daemon", anvilPID = anvilPID, error = e.msg
|
||||||
|
|
||||||
proc setupOnchainGroupManager*(
|
proc setupOnchainGroupManager*(
|
||||||
ethClientUrl: string = EthClient, amountEth: UInt256 = 10.u256
|
ethClientUrl: string = EthClient, amountEth: UInt256 = 10.u256
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user