Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kill any previously running processes before starting yaci-cli. #96

Merged
merged 4 commits into from
Jan 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package com.bloxbean.cardano.yacicli;

import com.bloxbean.cardano.yacicli.localcluster.config.GenesisConfig;
import com.bloxbean.cardano.yacicli.util.ProcessUtil;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
Expand All @@ -11,13 +14,20 @@
@EnableConfigurationProperties(GenesisConfig.class)
@Slf4j
public class YaciCliApplication {
@Autowired
private ProcessUtil processUtil;

public static void main(String[] args) {
new SpringApplicationBuilder(YaciCliApplication.class)
.logStartupInfo(false)
.run(args);
}

@PostConstruct
public void stopRunningProcesses() {
processUtil.killRunningProcesses();
}

@PreDestroy
public void onShutDown() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
@RequiredArgsConstructor
@Slf4j
public class ClusterStartService {
public static final String SUBMIT_API_PROCESS_NAME = "submit-api";
public static final String NODE_PROCESS_NAME = "node";
private final ClusterConfig clusterConfig;
private final ClusterPortInfoHelper clusterPortInfoHelper;
private final ProcessUtil processUtil;
Expand Down Expand Up @@ -123,6 +125,7 @@ public void stopCluster(Consumer<String> writer) {
if (processes != null && processes.size() > 0)
writer.accept(info("Trying to stop the running cluster ..."));

boolean error = false;
for (Process process : processes) {
if (process != null && process.isAlive()) {
process.descendants().forEach(processHandle -> {
Expand All @@ -139,6 +142,12 @@ public void stopCluster(Consumer<String> writer) {
}
}

if (!error) {
//clean pid files
processUtil.deletePidFile(NODE_PROCESS_NAME);
processUtil.deletePidFile(SUBMIT_API_PROCESS_NAME);
}

logs.clear();
submitApiLogs.clear();
} catch (Exception e) {
Expand Down Expand Up @@ -200,7 +209,7 @@ private Process startNode(Path clusterFolder, ClusterInfo clusterInfo, Consumer<
builder.directory(nodeStartDir);

writer.accept(success("Starting node from directory : " + nodeStartDir.getAbsolutePath()));
Process process = processUtil.startLongRunningProcess("Node", builder, logs, writer);
Process process = processUtil.startLongRunningProcess(NODE_PROCESS_NAME, builder, logs, writer);
if (process == null) return null;

Path nodeSocketPath = clusterFolder.resolve(ClusterConfig.NODE_FOLDER_PREFIX).resolve("node.sock");
Expand Down Expand Up @@ -234,7 +243,7 @@ private Process startSubmitApi(ClusterInfo clusterInfo, Path clusterFolder, Cons
File submitApiStartDir = new File(clusterFolderPath);
builder.directory(submitApiStartDir);

Process process = processUtil.startLongRunningProcess("SubmitApi", builder, submitApiLogs, writer);
Process process = processUtil.startLongRunningProcess(SUBMIT_API_PROCESS_NAME, builder, submitApiLogs, writer);
if (process == null) return null;

writer.accept(success("Started submit api : http://localhost:" + clusterPortInfoHelper.getSubmitApiPort(clusterInfo)));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,19 +34,17 @@
@RequiredArgsConstructor
@Slf4j
public class OgmiosService {
private final static String OGMIOS_PROCESS_NAME = "ogmios";
private final static String KUPO_PROCESS_NAME = "kupo";
private final ApplicationConfig appConfig;
private final ClusterService clusterService;
private final ClusterConfig clusterConfig;
private final ClusterPortInfoHelper clusterPortInfoHelper;
private final TemplateEngine templateEngine;
private final ProcessUtil processUtil;

private List<Process> processes = new ArrayList<>();

@Autowired
private TemplateEngine templateEngine;

@Autowired
private ProcessUtil processUtil;

private Queue<String> ogmiosLogs = EvictingQueue.create(300);
private Queue<String> kupoLogs = EvictingQueue.create(300);

Expand Down Expand Up @@ -181,6 +179,7 @@ public void handleClusterStopped(ClusterStopped clusterStopped) {
if (processes != null && processes.size() > 0)
writeLn(info("Trying to stop ogmios/kupo ..."));

boolean error = false;
for (Process process : processes) {
if (process != null && process.isAlive()) {
process.descendants().forEach(processHandle -> {
Expand All @@ -195,10 +194,17 @@ public void handleClusterStopped(ClusterStopped clusterStopped) {
writeLn(success("Killed : " + process));
} else {
writeLn(error("Process could not be killed : " + process));
error = true;
}
}
}

if (!error) {
//clean pid files
processUtil.deletePidFile(OGMIOS_PROCESS_NAME);
processUtil.deletePidFile(KUPO_PROCESS_NAME);
}

ogmiosLogs.clear();
} catch (Exception e) {
log.error("Error stopping process", e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import com.bloxbean.cardano.yacicli.localcluster.events.ClusterStopped;
import com.bloxbean.cardano.yacicli.util.PortUtil;
import com.bloxbean.cardano.yacicli.util.ProcessStream;
import com.bloxbean.cardano.yacicli.util.ProcessUtil;
import com.google.common.collect.EvictingQueue;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -35,12 +36,14 @@
@RequiredArgsConstructor
@Slf4j
public class YaciStoreService {
private static final String STORE_PROCESS_NAME = "yaci-store";
private final ApplicationConfig appConfig;
private final ClusterService clusterService;
private final ClusterConfig clusterConfig;
private final JreResolver jreResolver;
private final YaciStoreConfigBuilder yaciStoreConfigBuilder;
private final YaciStoreCustomDbHelper customDBHelper;
private final ProcessUtil processUtil;

private List<Process> processes = new ArrayList<>();

Expand Down Expand Up @@ -73,6 +76,7 @@ public void handleClusterStarted(ClusterStarted clusterStarted) {
Process process = startStoreApp(clusterInfo, era);
if (process != null)
processes.add(process);

// Process viewerProcess = startViewerApp(clusterStarted.getClusterName());
// processes.add(viewerProcess);
} catch (Exception e) {
Expand Down Expand Up @@ -197,6 +201,8 @@ private Process startStoreApp(ClusterInfo clusterInfo, Era era) throws IOExcepti
writeLn("###########################################################################################################################");
}

processUtil.createProcessId(STORE_PROCESS_NAME, process);

return process;
}

Expand Down Expand Up @@ -249,6 +255,7 @@ public void handleClusterStopped(ClusterStopped clusterStopped) {
if (processes != null && processes.size() > 0)
writeLn(info("Trying to stop yaci-store ..."));

boolean error = false;
for (Process process : processes) {
if (process != null && process.isAlive()) {
process.descendants().forEach(processHandle -> {
Expand All @@ -267,6 +274,11 @@ public void handleClusterStopped(ClusterStopped clusterStopped) {
}
}

if (!error) {
//clean pid files
processUtil.deletePidFile(STORE_PROCESS_NAME);
}

logs.clear();
} catch (Exception e) {
log.error("Error stopping process", e);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
package com.bloxbean.cardano.yacicli.util;

import com.bloxbean.cardano.yacicli.commands.common.ExecutorHelper;
import com.bloxbean.cardano.yacicli.localcluster.ClusterConfig;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;
import java.util.Queue;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
Expand All @@ -16,6 +23,7 @@
@RequiredArgsConstructor
public class ProcessUtil {
private final ExecutorHelper executorHelper;
private final ClusterConfig clusterConfig;

public boolean executeAndFinish(ProcessBuilder processBuilder, String scriptPurpose, Consumer<String> writer) {
try {
Expand Down Expand Up @@ -75,11 +83,121 @@ public Process startLongRunningProcess(String processName, ProcessBuilder builde
return null;
}

createProcessId(processName, process);

//stop consuming error stream
errorStream.stop();
return process;
}

public String createProcessId(String processName, Process process) {
try {
var yaciCliHome = clusterConfig.getYaciCliHome();
// Validate the yaciCliHome directory
Path homePath = Paths.get(yaciCliHome);
if (!Files.exists(homePath)) {
writeLn(error("yaci-cli home directory does not exist: " + yaciCliHome));
return null;
}

if (!Files.isDirectory(homePath)) {
writeLn(error("yaci-cli home path is not a directory: " + yaciCliHome));
return null;
}

Path pids = homePath.resolve("pids");
if (!Files.exists(pids))
pids.toFile().mkdirs();

Path pidFilePath = pids.resolve(processName + ".pid");
long pid = process.pid();
Files.writeString(pidFilePath, String.valueOf(pid));

// Return the full path to the created PID file as a string
return pidFilePath.toString();
} catch (IOException e) {
writeLn(error("Failed to create the PID file: " + e.getMessage()));
return null;
}
}

public void deletePidFile(String processName) {
var yaciCliHome = clusterConfig.getYaciCliHome();
// Validate the yaciCliHome directory
Path homePath = Paths.get(yaciCliHome);
Path pids = homePath.resolve("pids");

var pidPath = pids.resolve(processName + ".pid");
if (Files.exists(pidPath)) {
pidPath.toFile().delete();
writeLn(info("Deleted pid file : " + processName + ".pid"));
}
}

public void killRunningProcesses() {
var yaciCliHome = clusterConfig.getYaciCliHome();

// Validate the yaciCliHome directory
Path homePath = Paths.get(yaciCliHome);
if (!Files.exists(homePath)) {
writeLn(error("The yaciCliHome directory does not exist: " + yaciCliHome));
return;
}
if (!Files.isDirectory(homePath)) {
writeLn(error("The yaciCliHome path is not a directory: " + yaciCliHome));
return;
}

// Resolve the pids directory
Path pidsDir = homePath.resolve("pids");
if (!Files.exists(pidsDir) || !Files.isDirectory(pidsDir)) {
writeLn(error("The pids directory does not exist or is not a directory: " + pidsDir));
return;
}

List<Long> pidList = new ArrayList<>();
try (DirectoryStream<Path> pidFiles = Files.newDirectoryStream(pidsDir, "*.pid")) {
for (Path pidFile : pidFiles) {
try {
// Read the PID from the file
String pidString = Files.readString(pidFile).trim();
if (!pidString.isEmpty()) {
pidList.add(Long.parseLong(pidString));
}
} catch (IOException | NumberFormatException e) {
writeLn(error("Failed to read or parse PID file: " + pidFile + " - " + e.getMessage()));
}
}
} catch (IOException e) {
writeLn(error("Failed to list PID files in directory: " + pidsDir + " : " + e.getMessage()));
return;
}

var deletedPids = new ArrayList<>();
for (Long pid : pidList) {
try {
ProcessHandle.of(pid)
.ifPresent(processHandle -> {
processHandle.descendants().forEach(ph -> {
deletedPids.add(ph.pid());
ph.destroyForcibly();
});
var result = processHandle.destroyForcibly();
if (!result) {
writeLn(error("Failed to kill process with PID : " + pid));
} else {
deletedPids.add(processHandle.pid());
}
});
} catch (Exception e) {
writeLn(error("Failed to kill process with PID: " + pid + " - " + e.getMessage()));
}
}

if (!deletedPids.isEmpty()) {
writeLn(info("Found existing processes. Killed processes with pids: " + deletedPids));
}
}
public String executeAndReturnOutput(ProcessBuilder processBuilder) {
try {
StringBuilder sb = new StringBuilder();
Expand Down
2 changes: 1 addition & 1 deletion config/version
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
tag=0.10.0-preview4
tag=0.10.0-preview5
revision=
12 changes: 6 additions & 6 deletions npm/yaci-devkit/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading