This is an automated email from the ASF dual-hosted git repository.
bejancsaba pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/nifi.git
The following commit(s) were added to refs/heads/main by this push:
new 3c3cf9976e NIFI-11761 Fixed MiNiFi restart issue when graceful
shutdown period expires. MiNiFi restart sends bootstrap to background
3c3cf9976e is described below
commit 3c3cf9976ec18a9b67dc5a435a01e4d48be12151
Author: Ferenc Kis <[email protected]>
AuthorDate: Wed Jun 28 16:24:00 2023 +0200
NIFI-11761 Fixed MiNiFi restart issue when graceful shutdown period
expires. MiNiFi restart sends bootstrap to background
Signed-off-by: Csaba Bejan <[email protected]>
This closes #7448.
---
.../apache/nifi/minifi/bootstrap/RunMiNiFi.java | 9 +++++--
.../nifi/minifi/bootstrap/command/StopRunner.java | 4 ++-
.../minifi/bootstrap/util/UnixProcessUtils.java | 30 ++++++++++++++++++----
.../src/main/resources/bin/minifi.sh | 8 +++---
4 files changed, 39 insertions(+), 12 deletions(-)
diff --git
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/RunMiNiFi.java
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/RunMiNiFi.java
index 1c141547a0..dac7febab6 100644
---
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/RunMiNiFi.java
+++
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/RunMiNiFi.java
@@ -14,6 +14,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package org.apache.nifi.minifi.bootstrap;
import static java.util.Collections.singleton;
@@ -76,6 +77,8 @@ public class RunMiNiFi implements ConfigurationFileHolder {
private static final String STATUS_FILE_PORT_KEY = "port";
private static final String STATUS_FILE_SECRET_KEY = "secret.key";
private static final String ACKNOWLEDGE_OPERATION =
"ACKNOWLEDGE_OPERATION";
+ private static final String PROCESS_KILL_SUCCESS_CHECK_RETRIES_KEY =
"process.kill.success.check.retries";
+ private static final String PROCESS_KILL_SUCCESS_CHECK_RETRIES_DEFAULT =
"30";
private final BootstrapFileProvider bootstrapFileProvider;
private final ConfigurationChangeCoordinator
configurationChangeCoordinator;
@@ -98,18 +101,20 @@ public class RunMiNiFi implements ConfigurationFileHolder {
bootstrapFileProvider = new BootstrapFileProvider(bootstrapConfigFile);
objectMapper = getObjectMapper();
Properties properties = bootstrapFileProvider.getStatusProperties();
+ Properties bootstrapProperties =
bootstrapFileProvider.getBootstrapProperties();
miNiFiParameters = new MiNiFiParameters(
Optional.ofNullable(properties.getProperty(STATUS_FILE_PORT_KEY)).map(Integer::parseInt).orElse(UNINITIALIZED),
Optional.ofNullable(properties.getProperty(STATUS_FILE_PID_KEY)).map(Integer::parseInt).orElse(UNINITIALIZED),
properties.getProperty(STATUS_FILE_SECRET_KEY)
);
- ProcessUtils processUtils = new UnixProcessUtils();
+ ProcessUtils processUtils = new UnixProcessUtils(Integer.parseInt(
+
bootstrapProperties.getProperty(PROCESS_KILL_SUCCESS_CHECK_RETRIES_KEY,
PROCESS_KILL_SUCCESS_CHECK_RETRIES_DEFAULT)));
miNiFiCommandSender = new MiNiFiCommandSender(miNiFiParameters,
objectMapper);
MiNiFiStatusProvider miNiFiStatusProvider = new
MiNiFiStatusProvider(miNiFiCommandSender, processUtils);
periodicStatusReporterManager =
- new
PeriodicStatusReporterManager(bootstrapFileProvider.getBootstrapProperties(),
miNiFiStatusProvider, miNiFiCommandSender, miNiFiParameters);
+ new PeriodicStatusReporterManager(bootstrapProperties,
miNiFiStatusProvider, miNiFiCommandSender, miNiFiParameters);
MiNiFiConfigurationChangeListener configurationChangeListener = new
MiNiFiConfigurationChangeListener(this, DEFAULT_LOGGER, bootstrapFileProvider);
configurationChangeCoordinator = new
ConfigurationChangeCoordinator(bootstrapFileProvider, this,
singleton(configurationChangeListener));
diff --git
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/command/StopRunner.java
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/command/StopRunner.java
index db980d5c52..a5f3413e94 100644
---
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/command/StopRunner.java
+++
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/command/StopRunner.java
@@ -45,7 +45,7 @@ public class StopRunner implements CommandRunner {
private final ProcessUtils processUtils;
public StopRunner(BootstrapFileProvider bootstrapFileProvider,
MiNiFiParameters miNiFiParameters, MiNiFiCommandSender miNiFiCommandSender,
- CurrentPortProvider currentPortProvider,
GracefulShutdownParameterProvider gracefulShutdownParameterProvider,
ProcessUtils processUtils) {
+ CurrentPortProvider currentPortProvider,
GracefulShutdownParameterProvider gracefulShutdownParameterProvider,
ProcessUtils processUtils) {
this.bootstrapFileProvider = bootstrapFileProvider;
this.miNiFiParameters = miNiFiParameters;
this.miNiFiCommandSender = miNiFiCommandSender;
@@ -56,6 +56,7 @@ public class StopRunner implements CommandRunner {
/**
* Shutdown the MiNiFi and the managing bootstrap process as well.
+ *
* @param args the input arguments
* @return status code
*/
@@ -94,6 +95,7 @@ public class StopRunner implements CommandRunner {
status = ERROR.getStatusCode();
}
} catch (IOException e) {
+ CMD_LOGGER.warn("An error has occurred while stopping MiNiFi.
Force killing process with pid=" + minifiPid, e);
killProcessTree(minifiPid);
} finally {
if (lockFile.exists() && !lockFile.delete()) {
diff --git
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/UnixProcessUtils.java
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/UnixProcessUtils.java
index 1a13138696..8a1a8ee65c 100644
---
a/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/UnixProcessUtils.java
+++
b/minifi/minifi-bootstrap/src/main/java/org/apache/nifi/minifi/bootstrap/util/UnixProcessUtils.java
@@ -37,6 +37,12 @@ import org.slf4j.LoggerFactory;
public class UnixProcessUtils implements ProcessUtils {
private static final Logger LOGGER =
LoggerFactory.getLogger(UnixProcessUtils.class);
+ private final int processKillCheckRetries;
+
+ public UnixProcessUtils(int processKillCheckRetries) {
+ this.processKillCheckRetries = processKillCheckRetries;
+ }
+
@Override
public boolean isProcessRunning(Long pid) {
if (pid == null) {
@@ -55,8 +61,8 @@ public class UnixProcessUtils implements ProcessUtils {
boolean running = false;
String line;
try (InputStream in = proc.getInputStream();
- Reader streamReader = new InputStreamReader(in);
- BufferedReader reader = new BufferedReader(streamReader)) {
+ Reader streamReader = new InputStreamReader(in);
+ BufferedReader reader = new BufferedReader(streamReader)) {
while ((line = reader.readLine()) != null) {
if (line.trim().startsWith(pidString)) {
@@ -113,14 +119,28 @@ public class UnixProcessUtils implements ProcessUtils {
killProcessTree(childPid);
}
- Runtime.getRuntime().exec(new String[]{"kill", "-9",
String.valueOf(pid)});
+ Runtime.getRuntime().exec(new String[] {"kill", "-9",
String.valueOf(pid)});
+
+ int retries = processKillCheckRetries;
+ while (isProcessRunning(pid)) {
+ if (retries == 0) {
+ throw new IOException("Failed to stop process. Process is
still running after killing attempt with pid=" + pid);
+ }
+ LOGGER.warn("Process is still running after killing attempt with
pid=" + pid);
+ retries--;
+ try {
+ Thread.sleep(1000);
+ } catch (InterruptedException e) {
+ DEFAULT_LOGGER.warn("Thread interrupted while waiting for
killing process with pid=" + pid);
+ }
+ }
}
private List<Long> getChildProcesses(Long ppid) throws IOException {
- Process proc = Runtime.getRuntime().exec(new String[]{"ps", "-o",
"pid", "--no-headers", "--ppid", String.valueOf(ppid)});
+ Process proc = Runtime.getRuntime().exec(new String[] {"ps", "-o",
"pid", "--no-headers", "--ppid", String.valueOf(ppid)});
List<Long> childPids = new ArrayList<>();
try (InputStream in = proc.getInputStream();
- BufferedReader reader = new BufferedReader(new
InputStreamReader(in))) {
+ BufferedReader reader = new BufferedReader(new
InputStreamReader(in))) {
String line;
while ((line = reader.readLine()) != null) {
diff --git
a/minifi/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi.sh
b/minifi/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi.sh
index 5c33b7b2ff..c5c0004bd3 100755
---
a/minifi/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi.sh
+++
b/minifi/minifi-nar-bundles/minifi-framework-bundle/minifi-framework/minifi-resources/src/main/resources/bin/minifi.sh
@@ -326,23 +326,23 @@ run() {
fi
if [ "$1" = "run" ]; then
- # Use exec to handover PID to RunMiNiFi java process, instead of foking
it as a child process
+ # Use exec to handover PID to RunMiNiFi java process, instead of forking
it as a child process
RUN_MINIFI_CMD="exec ${RUN_MINIFI_CMD}"
fi
# run 'start' in the background because the process will continue to run,
monitoring MiNiFi.
# all other commands will terminate quickly so want to just wait for them
- if [ "$1" = "start" ]; then
+ if [ "$1" = "start" ] || [ "$1" = "restart" ]; then
(eval "cd ${MINIFI_HOME} && ${RUN_MINIFI_CMD}" &)
else
eval "cd ${MINIFI_HOME} && ${RUN_MINIFI_CMD}"
fi
EXIT_STATUS=$?
- # Wait just a bit (3 secs) to wait for the logging to finish and then echo
a new-line.
+ # Wait just a bit (5 secs) to wait for the logging to finish and then echo
a new-line.
# We do this to avoid having logs spewed on the console after running the
command and then not giving
# control back to the user
- sleep 3
+ sleep 5
echo
}