Skip to content

Commit f9cbd60

Browse files
committed
Fix #7 - allow creation of clients with a given number of http connections, static list of open clients etc
1 parent 8ffa055 commit f9cbd60

3 files changed

Lines changed: 74 additions & 33 deletions

File tree

src/main/java/com/algorithmia/Algorithmia.java

Lines changed: 35 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,14 @@
88
* Instantiate Algorithmia clients for calling algorithms and accessing data
99
*/
1010
public final class Algorithmia {
11-
11+
private static final int DEFAULT_MAX_CONNECTIONS = 10;
1212
private static AlgorithmiaClient defaultClient = null;
1313

1414
private Algorithmia() {} // Not instantiable
1515

1616
/**
1717
* Returns the default Algorithmia client which will
18-
* look for ALGORITHMI_API_KEY environment variable or java property
18+
* look for ALGORITHMIA_API_KEY environment variable or java property
1919
* If no key is found, then requests will be unauthenticated which only works
2020
* when making requests from an algorithm running within the Algorithmia cluster
2121
* @return an Algorithmia client
@@ -24,11 +24,22 @@ public static AlgorithmiaClient client() {
2424
return getDefaultClient();
2525
}
2626

27+
/**
28+
* Returns the default Algorithmia client which will
29+
* look for ALGORITHMIA_API_KEY environment variable or java property
30+
* If no key is found, then requests will be unauthenticated which only works
31+
* when making requests from an algorithm running within the Algorithmia cluster
32+
* @param maxConnections max number of concurrent connections to hold open to Algorithmia
33+
* @return an Algorithmia client
34+
*/
35+
public static AlgorithmiaClient client(int maxConnections) {
36+
return new AlgorithmiaClient(null, maxConnections);
37+
}
2738

2839
/**
2940
* Builds an Algorithmia client that makes all requests with your API key
3041
* If API key is null, the default client is returned, which will
31-
* look for ALGORITHMI_API_KEY environment variable or java property
42+
* look for ALGORITHMIA_API_KEY environment variable or java property
3243
* If no key is found, then requests will be unauthenticated which only works
3344
* when making requests from an algorithm running within the Algorithmia cluster
3445
* @param simpleKey API Key for simple authentication (prefixed with "sim")
@@ -38,10 +49,29 @@ public static AlgorithmiaClient client(String simpleKey) {
3849
if(simpleKey == null) {
3950
return getDefaultClient();
4051
} else {
41-
return new AlgorithmiaClient(new SimpleAuth(simpleKey));
52+
return new AlgorithmiaClient(new SimpleAuth(simpleKey), DEFAULT_MAX_CONNECTIONS);
4253
}
4354
}
4455

56+
/**
57+
* Builds an Algorithmia client that makes all requests with your API key
58+
* If API key is null, the default client is returned, which will
59+
* look for ALGORITHMIA_API_KEY environment variable or java property
60+
* If no key is found, then requests will be unauthenticated which only works
61+
* when making requests from an algorithm running within the Algorithmia cluster
62+
* @param simpleKey API Key for simple authentication (prefixed with "sim")
63+
* @param maxConnections max number of concurrent connections to hold open to Algorithmia
64+
* @return an Algorithmia client
65+
*/
66+
public static AlgorithmiaClient client(String simpleKey, int maxConnections) {
67+
if(simpleKey == null) {
68+
return getDefaultClient();
69+
} else {
70+
return new AlgorithmiaClient(new SimpleAuth(simpleKey), maxConnections);
71+
}
72+
}
73+
74+
4575
/**
4676
* Initialize an Algorithm object using the default client
4777
* @param algoUri the algorithm's URI, e.g., algo://user/algoname
@@ -71,7 +101,7 @@ public static DataFile file(String path) {
71101

72102
private static AlgorithmiaClient getDefaultClient() {
73103
if(defaultClient == null) {
74-
defaultClient = new AlgorithmiaClient();
104+
defaultClient = new AlgorithmiaClient(null, DEFAULT_MAX_CONNECTIONS);
75105
}
76106
return defaultClient;
77107
}

src/main/java/com/algorithmia/AlgorithmiaClient.java

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,13 @@
1010
public final class AlgorithmiaClient {
1111
private HttpClient client;
1212
/**
13-
* Instantiate Algorithmia client without credentials
14-
* This only works for when running the client on top of the Algorithmia platform
13+
* Instantiate Algorithmia client with the given auth and max number of connections
14+
* @param auth Algorithmia Auth object, a null auth object is valid, though only
15+
* correct for within the Algorithmia platform
16+
* @param maxConnections
1517
*/
16-
protected AlgorithmiaClient() {
17-
this.client = new HttpClient(null);
18-
}
19-
20-
/**
21-
* Instantiate Algorithmia client with auth
22-
* @param auth Algorithmia Auth object
23-
*/
24-
protected AlgorithmiaClient(Auth auth) {
25-
this.client = new HttpClient(auth);
18+
protected AlgorithmiaClient(Auth auth, int maxConnections) {
19+
this.client = new HttpClient(auth, maxConnections);
2620
}
2721

2822
/**

src/main/java/com/algorithmia/client/HttpClient.java

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import org.apache.http.entity.ContentType;
1010
import org.apache.http.entity.StringEntity;
1111
import org.apache.http.impl.nio.client.CloseableHttpAsyncClient;
12+
import org.apache.http.impl.nio.client.HttpAsyncClientBuilder;
1213
import org.apache.http.impl.nio.client.HttpAsyncClients;
1314
import org.apache.http.nio.client.methods.AsyncByteConsumer;
1415
import org.apache.http.nio.client.methods.ZeroCopyConsumer;
@@ -25,6 +26,8 @@
2526
import java.net.URI;
2627
import java.net.URISyntaxException;
2728
import java.util.HashMap;
29+
import java.util.LinkedList;
30+
import java.util.List;
2831
import java.util.Map;
2932
import java.util.concurrent.ExecutionException;
3033
import java.util.concurrent.CancellationException;
@@ -43,30 +46,37 @@ public class HttpClient {
4346

4447
private static String userAgent = "algorithmia-java/" + "1.0.8";
4548

46-
private CloseableHttpAsyncClient client;
47-
48-
public HttpClient(Auth auth) {
49-
this.auth = auth;
50-
initializeClient();
51-
}
52-
53-
private void initializeClient() {
54-
// Note: the default client has a low max number of concurrent connections, can create a
55-
// custom client with a higher limit if desired, but at least creating multiple Algorithmia clients
56-
// will guaranteed increase parallelization
57-
client = HttpAsyncClients.createDefault();
58-
client.start();
49+
private static List<CloseableHttpAsyncClient> clients = new LinkedList<CloseableHttpAsyncClient>();
5950

51+
static {
6052
Runtime.getRuntime().addShutdownHook(new Thread(){
6153
@Override
6254
public void run(){
63-
try {
64-
client.close();
65-
} catch(IOException e) {}
55+
synchronized (clients) {
56+
for (CloseableHttpAsyncClient client : clients) {
57+
try {
58+
client.close();
59+
} catch (IOException e) {}
60+
}
61+
}
6662
}
6763
});
6864
}
6965

66+
private final CloseableHttpAsyncClient client;
67+
public HttpClient(Auth auth, int maxConnections) {
68+
this.auth = auth;
69+
70+
client = HttpAsyncClientBuilder.create()
71+
.setMaxConnTotal(maxConnections)
72+
.setMaxConnPerRoute(maxConnections).build();
73+
74+
synchronized (clients) {
75+
clients.add(client);
76+
}
77+
client.start();
78+
}
79+
7080
/**
7181
* Modifies request in place to add on any query parameters
7282
*/
@@ -254,4 +264,11 @@ protected HttpResponse buildResult(final HttpContext context) throws Exception {
254264
protected void onByteReceived(final ByteBuffer buf, final IOControl ioctrl) {
255265
}
256266
}
267+
268+
@Override
269+
protected void finalize() {
270+
synchronized (clients) {
271+
clients.remove(client);
272+
}
273+
}
257274
}

0 commit comments

Comments
 (0)