use of services.moleculer.service.ActionEndpoint in project moleculer-java by moleculer-java.
the class DefaultCircuitBreaker method callWithBreaker.
// --- CALL SERVICE WITH BREAKER FUNCTION ---
protected Promise callWithBreaker(String name, Tree params, CallOptions.Options opts, int remaining, Context parent) {
EndpointKey endpointKey = null;
ErrorCounter errorCounter = null;
try {
// Get the first recommended Endpoint and Error Counter
String targetID = opts == null ? null : opts.nodeID;
ActionEndpoint action = (ActionEndpoint) serviceRegistry.getAction(name, targetID);
String nodeID = action.getNodeID();
endpointKey = new EndpointKey(nodeID, name);
errorCounter = errorCounters.get(endpointKey);
// Check availability of the Endpoint (if endpoint isn't targetted)
if (targetID == null) {
LinkedHashSet<String> nodeIDs = new LinkedHashSet<>(maxSameNodes * 2);
int sameNodeCounter = 0;
long now;
if (errorCounter == null) {
now = 0;
} else {
now = System.currentTimeMillis();
}
for (int i = 0; i < maxTries; i++) {
if (errorCounter == null || errorCounter.isAvailable(now)) {
// Endpoint is available
break;
}
// Store nodeID
if (!nodeIDs.add(nodeID)) {
sameNodeCounter++;
if (sameNodeCounter >= maxSameNodes) {
// The "maxSameNodes" limit is reached
break;
}
}
// Try to choose another endpoint
action = (ActionEndpoint) serviceRegistry.getAction(name, targetID);
nodeID = action.getNodeID();
endpointKey = new EndpointKey(nodeID, name);
errorCounter = errorCounters.get(endpointKey);
}
}
// Create new Context
Context ctx = contextFactory.create(name, params, opts, parent);
// Invoke Endpoint
final ErrorCounter currentCounter = errorCounter;
final EndpointKey currentKey = endpointKey;
return Promise.resolve(action.handler(ctx)).then(rsp -> {
// Reset error counter
if (currentCounter != null) {
currentCounter.reset();
}
// Return response
return rsp;
}).catchError(cause -> {
// Increment error counter
increment(currentCounter, currentKey, cause, System.currentTimeMillis());
// Return with error
if (remaining < 1) {
return cause;
}
// Retry
return retryWithBreaker(cause, name, params, opts, remaining, parent);
});
} catch (Throwable cause) {
// Increment error counter
increment(errorCounter, endpointKey, cause, System.currentTimeMillis());
// Reject
if (remaining < 1) {
return Promise.reject(cause);
}
// Retry
return retryWithBreaker(cause, name, params, opts, remaining, parent);
}
}
Aggregations