Skip to content

Commit

Permalink
Fix #302 jvm exit delayed by lingering threads
Browse files Browse the repository at this point in the history
  • Loading branch information
gschueler committed Sep 25, 2020
1 parent be586c4 commit f480856
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 20 deletions.
18 changes: 14 additions & 4 deletions rd-api-client/src/main/java/org/rundeck/client/RundeckClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package org.rundeck.client;

import okhttp3.Cache;
import okhttp3.HttpUrl;
import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient;
Expand Down Expand Up @@ -294,10 +295,11 @@ private Client<A> buildRundeckClient() {

okhttp.addInterceptor(new StaticHeaderInterceptor("User-Agent", userAgent));

OkHttpClient okhttp = this.okhttp.build();

Retrofit build = new Retrofit.Builder()
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(apiBaseUrl)
.client(okhttp.build())
.client(okhttp)
.addConverterFactory(new QualifiedTypeConverterFactory(
JacksonConverterFactory.create(),
JaxbConverterFactory.create(),
Expand All @@ -306,8 +308,16 @@ private Client<A> buildRundeckClient() {
.build();

return new Client<>(
build.create(api),
build,
retrofit.create(api),
retrofit,
() -> {
okhttp.dispatcher().executorService().shutdown();
okhttp.connectionPool().evictAll();
Cache cache = okhttp.cache();
if (null != cache && !cache.isClosed()) {
cache.close();
}
},
appBaseUrl,
apiBaseUrl,
usedApiVers,
Expand Down
28 changes: 28 additions & 0 deletions rd-api-client/src/main/java/org/rundeck/client/util/Client.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public class Client<T> implements ServiceClient<T> {
private final String apiBaseUrl;
private final boolean allowVersionDowngrade;
private final Logger logger;
private final Closeable closer;

public interface Logger {
void output(String out);
Expand All @@ -86,6 +87,33 @@ public Client(
this.apiVersion = apiVersion;
this.allowVersionDowngrade = allowVersionDowngrade;
this.logger = logger;
this.closer = () -> {
};
}
public Client(
final T service,
final Retrofit retrofit,
final Closeable closer,
final String appBaseUrl,
final String apiBaseUrl,
final int apiVersion,
final boolean allowVersionDowngrade,
final Logger logger
)
{
this.service = service;
this.retrofit = retrofit;
this.appBaseUrl = appBaseUrl;
this.apiBaseUrl = apiBaseUrl;
this.apiVersion = apiVersion;
this.allowVersionDowngrade = allowVersionDowngrade;
this.logger = logger;
this.closer = closer;
}

@Override
public void close() throws IOException {
closer.close();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@
import retrofit2.Response;
import retrofit2.Retrofit;

import java.io.Closeable;
import java.io.IOException;
import java.util.function.Function;

/**
* @author greg
* @since 10/19/17
*/
public interface ServiceClient<T> {
public interface ServiceClient<T> extends Closeable {
/**
* @param mediaType1 test type
* @param types list of media types
Expand Down
42 changes: 27 additions & 15 deletions rd-cli-tool/src/main/java/org/rundeck/client/tool/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.rundeck.client.tool.extension.RdCommandExtension;
import org.rundeck.client.tool.util.AdaptedToolbeltOutput;
import org.rundeck.client.tool.util.ExtensionLoaderUtil;
import org.rundeck.client.tool.util.Resources;
import org.rundeck.client.util.*;
import org.rundeck.toolbelt.*;
import org.rundeck.toolbelt.format.json.jackson.JsonFormatter;
Expand All @@ -37,6 +38,8 @@
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.representer.Representer;

import java.io.Closeable;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.*;
Expand Down Expand Up @@ -64,18 +67,21 @@ public class Main {
RundeckClient.Builder.getUserAgent("rd-cli-tool/" + org.rundeck.client.Version.VERSION);

public static void main(String[] args) throws CommandRunFailure {
Rd rd = new Rd(new Env());
Tool tool = tool(rd);
boolean success = false;
try {
success = tool.runMain(args, false);
} catch (RequestFailed failure) {
rd.getOutput().error(failure.getMessage());
if (rd.getDebugLevel() > 0) {
StringWriter sb = new StringWriter();
failure.printStackTrace(new PrintWriter(sb));
rd.getOutput().error(sb.toString());
try (Rd rd = new Rd(new Env())) {
Tool tool = tool(rd);
try {
success = tool.runMain(args, false);
} catch (RequestFailed failure) {
rd.getOutput().error(failure.getMessage());
if (rd.getDebugLevel() > 0) {
StringWriter sb = new StringWriter();
failure.printStackTrace(new PrintWriter(sb));
rd.getOutput().error(sb.toString());
}
}
} catch (IOException e) {
e.printStackTrace();
}
if (!success) {
System.exit(2);
Expand Down Expand Up @@ -232,7 +238,8 @@ public static Tool tool(final Rd rd) {
return belt.buckle();
}

static class Rd extends ExtConfigSource implements RdApp, RdClientConfig {
static class Rd extends ExtConfigSource implements RdApp, RdClientConfig, Closeable {
private final Resources resources = new Resources();
Client<RundeckApi> client;
private CommandOutput output;

Expand Down Expand Up @@ -264,7 +271,7 @@ public String getDateFormat() {
public Client<RundeckApi> getClient() throws InputError {
if (null == client) {
try {
client = Main.createClient(this);
client = resources.add(Main.createClient(this));
} catch (ConfigSourceError configSourceError) {
throw new InputError(configSourceError.getMessage());
}
Expand All @@ -275,7 +282,7 @@ public Client<RundeckApi> getClient() throws InputError {
@Override
public Client<RundeckApi> getClient(final int version) throws InputError {
try {
client = Main.createClient(this, version);
client = resources.add(Main.createClient(this, version));
} catch (ConfigSourceError configSourceError) {
throw new InputError(configSourceError.getMessage());
}
Expand All @@ -285,7 +292,7 @@ public Client<RundeckApi> getClient(final int version) throws InputError {
@Override
public <T> ServiceClient<T> getClient(final Class<T> api, final int version) throws InputError {
try {
return Main.createClient(this, api, version);
return resources.add(Main.createClient(this, api, version));
} catch (ConfigSourceError configSourceError) {
throw new InputError(configSourceError.getMessage());
}
Expand All @@ -294,7 +301,7 @@ public <T> ServiceClient<T> getClient(final Class<T> api, final int version) thr
@Override
public <T> ServiceClient<T> getClient(final Class<T> api) throws InputError {
try {
return Main.createClient(this, api, null);
return resources.add(Main.createClient(this, api, null));
} catch (ConfigSourceError configSourceError) {
throw new InputError(configSourceError.getMessage());
}
Expand Down Expand Up @@ -328,6 +335,11 @@ public CommandOutput getOutput() {
public void setOutput(CommandOutput output) {
this.output = output;
}

@Override
public void close() throws IOException {
resources.close();
}
}

private static void setupColor(final ToolBelt belt, RdClientConfig config) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package org.rundeck.client.tool.util;

import java.io.Closeable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

/**
* Holds collection of closeable resources
*/
public class Resources
implements Closeable
{
private final Collection<Closeable> closeableResources = new ArrayList<>();

public <T extends Closeable> T add(T closeable) {
closeableResources.add(closeable);
return closeable;
}

@Override
public void close() throws IOException {
closeableResources.forEach(
closeable -> {
try {
closeable.close();
} catch (IOException e) {
e.printStackTrace();
}
}
);
closeableResources.clear();
}
}

0 comments on commit f480856

Please sign in to comment.