Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 149a543

Browse files
committed
changed cache bulk request function - bulk re-populate begins at half
cache size, but adaptively changes with respect to bits remaining on server
1 parent c60f7ba commit 149a543

File tree

3 files changed

+84
-29
lines changed

3 files changed

+84
-29
lines changed

RandomJSONRPC/src/org/random/api/RandomOrgCache.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import java.util.logging.Level;
66
import java.util.logging.Logger;
77

8+
import org.random.api.exception.RandomOrgInsufficientBitsError;
9+
810
import com.google.gson.JsonObject;
911

1012
/** Precache class for frequently used requests.
@@ -30,7 +32,7 @@ public class RandomOrgCache<T> {
3032
private LinkedList<T> queue = new LinkedList<T>();
3133
private int cacheSize;
3234

33-
private int bulkRequestNumber, requestNumber;
35+
private int bulkRequestNumber, requestNumber, requestSize;
3436

3537
// lock to allow notification when an item is consumed or pause state is updated.
3638
private Object lock = new Object();
@@ -49,9 +51,10 @@ public class RandomOrgCache<T> {
4951
** @param cacheSize number of request responses to try maintain.
5052
** @param bulkRequestNumber if request is set to be issued in bulk, number of result sets in a bulk request, else 0.
5153
** @param requestNumber if request is set to be issued in bulk, number of results in a single request, else 0.
54+
** @param singleRequestSize in bits for adjusting bulk requests if bits are in short supply on the server.
5255
**/
5356
protected RandomOrgCache(JsonObjectInputCallable<JsonObject> requestFunction, JsonObjectInputCallable<T> processFunction,
54-
JsonObject request, int cacheSize, int bulkRequestNumber, int requestNumber) {
57+
JsonObject request, int cacheSize, int bulkRequestNumber, int requestNumber, int singleRequestSize) {
5558

5659
this.requestFunction = requestFunction;
5760
this.processFunction = processFunction;
@@ -62,6 +65,7 @@ protected RandomOrgCache(JsonObjectInputCallable<JsonObject> requestFunction, Js
6265

6366
this.bulkRequestNumber = bulkRequestNumber;
6467
this.requestNumber = requestNumber;
68+
this.requestSize = singleRequestSize;
6569

6670
// Thread to keep RandomOrgCache populated.
6771
Thread t = new Thread(new Runnable() {
@@ -121,7 +125,25 @@ protected void populateQueue() {
121125
}
122126
this.queue.offer(entry);
123127
}
128+
} catch (RandomOrgInsufficientBitsError e) {
129+
130+
// get bits left
131+
int bits = e.getBits();
132+
133+
// can we adapt bulk request size?
134+
if (bits != -1 && this.requestSize < bits) {
124135

136+
this.bulkRequestNumber = bits / this.requestSize;
137+
138+
// update bulk request size
139+
this.request.remove("n");
140+
this.request.addProperty("n", this.bulkRequestNumber*this.requestNumber);
141+
142+
// nope - so error
143+
} else {
144+
throw(e);
145+
}
146+
125147
} catch (Exception e) {
126148
// Don't handle failures from requestFunction(), Just try again later.
127149
LOGGER.log(Level.INFO, "RandomOrgCache populate Exception: " + e.getClass().getName() + ": " + e.getMessage());

RandomJSONRPC/src/org/random/api/RandomOrgClient.java

Lines changed: 46 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ public class RandomOrgClient {
8585
// On request fetch fresh allowance state if current state data is older than this value (1 hour)
8686
private static final int ALLOWANCE_STATE_REFRESH_SECONDS = 3600*1000;
8787

88+
// default data sizes in bits
89+
private static final int UUID_SIZE = 122;
90+
8891
// Maintain a dictionary of API keys and their instances.
8992
private static HashMap<String, RandomOrgClient> keyIndexedInstances = new HashMap<String, RandomOrgClient>();
9093

@@ -1079,9 +1082,9 @@ public RandomOrgCache<int[]> createIntegerCache(int n, int min, int max, boolean
10791082
int bulkN = 0;
10801083

10811084
// If possible, make requests more efficient by bulk-ordering from the server.
1082-
// Either 5 sets of items at a time, or cache_size/2 if 5 >= cache_size.
1085+
// initially set at cache_size/2, but cache will auto-shrink bulk request size if requests can't be fulfilled.
10831086
if (replacement) {
1084-
bulkN = 5 >= cacheSize ? cacheSize/2 : 5;
1087+
bulkN = cacheSize/2;
10851088
request.addProperty("n", bulkN*n);
10861089

10871090
// not possible to make the request more efficient
@@ -1092,10 +1095,13 @@ public RandomOrgCache<int[]> createIntegerCache(int n, int min, int max, boolean
10921095
// get the request object for use in all requests from this cache
10931096
request = this.generateKeyedRequest(request, INTEGER_METHOD);
10941097

1098+
// max single request size, in bits, for adjusting bulk requests later
1099+
int maxRequestSize = (int) Math.ceil(Math.log(max - min + 1)/Math.log(2) * n);
1100+
10951101
return new RandomOrgCache<int[]>(
10961102
new JsonObjectInputCallable<JsonObject>() {
10971103
@Override
1098-
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgInsufficientRequestsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
1104+
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgKeyNotRunningError, RandomOrgInsufficientRequestsError, RandomOrgInsufficientBitsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
10991105
return RandomOrgClient.this.sendRequest(this.input);
11001106
}
11011107
}, new JsonObjectInputCallable<int[]>() {
@@ -1104,7 +1110,7 @@ public int[] call() {
11041110
return RandomOrgClient.this.extractInts(this.input);
11051111
}
11061112
},
1107-
request, cacheSize, bulkN, n);
1113+
request, cacheSize, bulkN, n, maxRequestSize);
11081114
}
11091115

11101116
/** Get a RandomOrgCache to obtain random decimal fractions. The RandomOrgCache can be polled for new results
@@ -1143,9 +1149,9 @@ public RandomOrgCache<double[]> createDecimalFractionCache(int n, int decimalPla
11431149
int bulkN = 0;
11441150

11451151
// If possible, make requests more efficient by bulk-ordering from the server.
1146-
// Either 5 sets of items at a time, or cache_size/2 if 5 >= cache_size.
1152+
// initially set at cache_size/2, but cache will auto-shrink bulk request size if requests can't be fulfilled.
11471153
if (replacement) {
1148-
bulkN = 5 >= cacheSize ? cacheSize/2 : 5;
1154+
bulkN = cacheSize/2;
11491155
request.addProperty("n", bulkN*n);
11501156

11511157
// not possible to make the request more efficient
@@ -1156,10 +1162,13 @@ public RandomOrgCache<double[]> createDecimalFractionCache(int n, int decimalPla
11561162
// get the request object for use in all requests from this cache
11571163
request = this.generateKeyedRequest(request, DECIMAL_FRACTION_METHOD);
11581164

1165+
// max single request size, in bits, for adjusting bulk requests later
1166+
int maxRequestSize = (int) Math.ceil(Math.log(10)/Math.log(2) * decimalPlaces * n);
1167+
11591168
return new RandomOrgCache<double[]>(
11601169
new JsonObjectInputCallable<JsonObject>() {
11611170
@Override
1162-
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgInsufficientRequestsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
1171+
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgKeyNotRunningError, RandomOrgInsufficientRequestsError, RandomOrgInsufficientBitsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
11631172
return RandomOrgClient.this.sendRequest(this.input);
11641173
}
11651174
}, new JsonObjectInputCallable<double[]>() {
@@ -1168,7 +1177,7 @@ public double[] call() {
11681177
return RandomOrgClient.this.extractDoubles(this.input);
11691178
}
11701179
},
1171-
request, cacheSize, bulkN, n);
1180+
request, cacheSize, bulkN, n, maxRequestSize);
11721181
}
11731182

11741183
/** Get a RandomOrgCache to obtain random numbers. The RandomOrgCache can be polled for new results
@@ -1210,17 +1219,20 @@ public RandomOrgCache<double[]> createGaussianCache(int n, double mean, double s
12101219
int bulkN = 0;
12111220

12121221
// make requests more efficient by bulk-ordering from the server.
1213-
// Either 5 sets of items at a time, or cache_size/2 if 5 >= cache_size.
1214-
bulkN = 5 >= cacheSize ? cacheSize/2 : 5;
1222+
// initially set at cache_size/2, but cache will auto-shrink bulk request size if requests can't be fulfilled.
1223+
bulkN = cacheSize/2;
12151224
request.addProperty("n", bulkN*n);
12161225

12171226
// get the request object for use in all requests from this cache
12181227
request = this.generateKeyedRequest(request, GAUSSIAN_METHOD);
12191228

1229+
// max single request size, in bits, for adjusting bulk requests later
1230+
int maxRequestSize = (int) Math.ceil(Math.log(Math.pow(10, significantDigits))/Math.log(2) * n);
1231+
12201232
return new RandomOrgCache<double[]>(
12211233
new JsonObjectInputCallable<JsonObject>() {
12221234
@Override
1223-
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgInsufficientRequestsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
1235+
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgKeyNotRunningError, RandomOrgInsufficientRequestsError, RandomOrgInsufficientBitsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
12241236
return RandomOrgClient.this.sendRequest(this.input);
12251237
}
12261238
}, new JsonObjectInputCallable<double[]>() {
@@ -1229,7 +1241,7 @@ public double[] call() {
12291241
return RandomOrgClient.this.extractDoubles(this.input);
12301242
}
12311243
},
1232-
request, cacheSize, bulkN, n);
1244+
request, cacheSize, bulkN, n, maxRequestSize);
12331245
}
12341246

12351247
/** Get a RandomOrgCache to obtain random strings. The RandomOrgCache can be polled for new results
@@ -1273,9 +1285,9 @@ public RandomOrgCache<String[]> createStringCache(int n, int length, String char
12731285
int bulkN = 0;
12741286

12751287
// If possible, make requests more efficient by bulk-ordering from the server.
1276-
// Either 5 sets of items at a time, or cache_size/2 if 5 >= cache_size.
1288+
// initially set at cache_size/2, but cache will auto-shrink bulk request size if requests can't be fulfilled.
12771289
if (replacement) {
1278-
bulkN = 5 >= cacheSize ? cacheSize/2 : 5;
1290+
bulkN = cacheSize/2;
12791291
request.addProperty("n", bulkN*n);
12801292

12811293
// not possible to make the request more efficient
@@ -1286,10 +1298,13 @@ public RandomOrgCache<String[]> createStringCache(int n, int length, String char
12861298
// get the request object for use in all requests from this cache
12871299
request = this.generateKeyedRequest(request, STRING_METHOD);
12881300

1301+
// max single request size, in bits, for adjusting bulk requests later
1302+
int maxRequestSize = (int) Math.ceil(Math.log(characters.length())/Math.log(2) * length * n);
1303+
12891304
return new RandomOrgCache<String[]>(
12901305
new JsonObjectInputCallable<JsonObject>() {
12911306
@Override
1292-
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgInsufficientRequestsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
1307+
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgKeyNotRunningError, RandomOrgInsufficientRequestsError, RandomOrgInsufficientBitsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
12931308
return RandomOrgClient.this.sendRequest(this.input);
12941309
}
12951310
}, new JsonObjectInputCallable<String[]>() {
@@ -1298,7 +1313,7 @@ public String[] call() {
12981313
return RandomOrgClient.this.extractStrings(this.input);
12991314
}
13001315
},
1301-
request, cacheSize, bulkN, n);
1316+
request, cacheSize, bulkN, n, maxRequestSize);
13021317
}
13031318

13041319
/** Get a RandomOrgCache to obtain UUIDs. The RandomOrgCache can be polled for new results conforming to the
@@ -1330,17 +1345,20 @@ public RandomOrgCache<UUID[]> createUUIDCache(int n, int cacheSize) {
13301345
int bulkN = 0;
13311346

13321347
// make requests more efficient by bulk-ordering from the server.
1333-
// Either 5 sets of items at a time, or cache_size/2 if 5 >= cache_size.
1334-
bulkN = 5 >= cacheSize ? cacheSize/2 : 5;
1348+
// initially set at cache_size/2, but cache will auto-shrink bulk request size if requests can't be fulfilled.
1349+
bulkN = cacheSize/2;
13351350
request.addProperty("n", bulkN*n);
13361351

13371352
// get the request object for use in all requests from this cache
13381353
request = this.generateKeyedRequest(request, UUID_METHOD);
13391354

1355+
// max single request size, in bits, for adjusting bulk requests later
1356+
int maxRequestSize = n*UUID_SIZE;
1357+
13401358
return new RandomOrgCache<UUID[]>(
13411359
new JsonObjectInputCallable<JsonObject>() {
13421360
@Override
1343-
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgInsufficientRequestsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
1361+
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgKeyNotRunningError, RandomOrgInsufficientRequestsError, RandomOrgInsufficientBitsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
13441362
return RandomOrgClient.this.sendRequest(this.input);
13451363
}
13461364
}, new JsonObjectInputCallable<UUID[]>() {
@@ -1349,7 +1367,7 @@ public UUID[] call() {
13491367
return RandomOrgClient.this.extractUUIDs(this.input);
13501368
}
13511369
},
1352-
request, cacheSize, bulkN, n);
1370+
request, cacheSize, bulkN, n, maxRequestSize);
13531371
}
13541372

13551373
/** Get a RandomOrgCache to obtain random blobs. The RandomOrgCache can be polled for new results conforming
@@ -1388,17 +1406,20 @@ public RandomOrgCache<String[]> createBlobCache(int n, int size, String format,
13881406
int bulkN = 0;
13891407

13901408
// make requests more efficient by bulk-ordering from the server.
1391-
// Either 5 sets of items at a time, or cache_size/2 if 5 >= cache_size.
1392-
bulkN = 5 >= cacheSize ? cacheSize/2 : 5;
1409+
// initially set at cache_size/2, but cache will auto-shrink bulk request size if requests can't be fulfilled.
1410+
bulkN = cacheSize/2;
13931411
request.addProperty("n", bulkN*n);
13941412

13951413
// get the request object for use in all requests from this cache
13961414
request = this.generateKeyedRequest(request, BLOB_METHOD);
13971415

1416+
// max single request size, in bits, for adjusting bulk requests later
1417+
int maxRequestSize = n*size;
1418+
13981419
return new RandomOrgCache<String[]>(
13991420
new JsonObjectInputCallable<JsonObject>() {
14001421
@Override
1401-
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgInsufficientRequestsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
1422+
public JsonObject call() throws RandomOrgSendTimeoutException, RandomOrgKeyNotRunningError, RandomOrgInsufficientRequestsError, RandomOrgInsufficientBitsError, RandomOrgBadHTTPResponseException, RandomOrgRANDOMORGError, RandomOrgJSONRPCError, MalformedURLException, IOException {
14021423
return RandomOrgClient.this.sendRequest(this.input);
14031424
}
14041425
}, new JsonObjectInputCallable<String[]>() {
@@ -1407,7 +1428,7 @@ public String[] call() {
14071428
return RandomOrgClient.this.extractStrings(this.input);
14081429
}
14091430
},
1410-
request, cacheSize, bulkN, n);
1431+
request, cacheSize, bulkN, n, maxRequestSize);
14111432
}
14121433

14131434
// Methods for accessing server usage statistics.
@@ -2016,7 +2037,7 @@ protected HashMap<String, Object> sendRequestCore(JsonObject request) {
20162037
return ret;
20172038

20182039
} else if (code == 403) {
2019-
ret.put("exception", new RandomOrgInsufficientBitsError("Error " + code + ": " + message));
2040+
ret.put("exception", new RandomOrgInsufficientBitsError("Error " + code + ": " + message, this.bitsLeft));
20202041
return ret;
20212042

20222043
// RandomOrgRANDOMORGError from RANDOM.ORG Errors: https://api.random.org/json-rpc/1/error-codes

RandomJSONRPC/src/org/random/api/exception/RandomOrgInsufficientBitsError.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,27 @@
44
** request has exceeded its remaining server bits allowance. If the
55
** client is currently issuing large requests it may be possible to
66
** succeed with smaller requests. Use the client's getBitsLeft() call
7-
** to help determine if an alternative request size is appropriate.
7+
** or the getBits() in this class to help determine if an alternative
8+
** request size is appropriate.
89
**/
910
public class RandomOrgInsufficientBitsError extends RuntimeException {
1011

12+
private int bits = -1;
13+
1114
/** Constructs a new exception with the specified detail message.
1215
**
1316
** @param message @see java.lang.Exception#Exception(java.lang.String)
17+
** @param bits remaining just before error thrown
1418
**/
15-
public RandomOrgInsufficientBitsError(String message) {
19+
public RandomOrgInsufficientBitsError(String message, int bits) {
1620
super(message);
21+
22+
this.bits = bits;
23+
}
24+
25+
/** @return bits remaining just before error.
26+
**/
27+
public int getBits() {
28+
return this.bits;
1729
}
1830
}

0 commit comments

Comments
 (0)