@Override
	protected Promise call(String name, Tree params, Options opts, PacketStream stream, Context parent, String targetID,
			int remaining) {
		EndpointKey endpointKey = null;
		ErrorCounter errorCounter = null;
		try {

			// Get the first recommended Endpoint and Error Counter
			ActionEndpoint action = (ActionEndpoint) serviceRegistry.getAction(name, targetID);
			String nodeID = action.getNodeID();
			endpointKey = new EndpointKey(nodeID, name);
			errorCounter = getErrorCounter(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, null);
					nodeID = action.getNodeID();
					endpointKey = new EndpointKey(nodeID, name);
					errorCounter = getErrorCounter(endpointKey);
				}
			}

			// Create new Context
			Context ctx = contextFactory.create(name, params, opts, stream, 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());

				// Retry
				return retry(cause, name, params, opts, stream, parent, targetID, remaining);
			});

		} catch (Throwable cause) {

			// Increment error counter
			increment(errorCounter, endpointKey, cause, System.currentTimeMillis());

			// Retry
			return retry(cause, name, params, opts, stream, parent, targetID, remaining);
		}
	}
@ Override protected Promise call ( String name , Tree params , Options opts , PacketStream stream , Context parent , String targetID , int remaining ) { EndpointKey endpointKey = null ; ErrorCounter errorCounter = null ; try { ActionEndpoint action = ( ActionEndpoint ) serviceRegistry . getAction ( name , targetID ) ; String nodeID = action . getNodeID ( ) ; endpointKey = new EndpointKey ( nodeID , name ) ; errorCounter = getErrorCounter ( endpointKey ) ; 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 ) ) { break ; } if ( ! nodeIDs . add ( nodeID ) ) { sameNodeCounter ++ ; if ( sameNodeCounter >= maxSameNodes ) { break ; } } action = ( ActionEndpoint ) serviceRegistry . getAction ( name , null ) ; nodeID = action . getNodeID ( ) ; endpointKey = new EndpointKey ( nodeID , name ) ; errorCounter = getErrorCounter ( endpointKey ) ; } } Context ctx = contextFactory . create ( name , params , opts , stream , parent ) ; final ErrorCounter currentCounter = errorCounter ; final EndpointKey currentKey = endpointKey ; return Promise . resolve ( action . handler ( ctx ) ) . then ( rsp -> { if ( currentCounter != null ) { currentCounter . reset ( ) ; } return rsp ; } ) . catchError ( cause -> { increment ( currentCounter , currentKey , cause , System . currentTimeMillis ( ) ) ; return retry ( cause , name , params , opts , stream , parent , targetID , remaining ) ; } ) ; } catch ( Throwable cause ) { increment ( errorCounter , endpointKey , cause , System . currentTimeMillis ( ) ) ; return retry ( cause , name , params , opts , stream , parent , targetID , remaining ) ; } }
--- CALL SERVICE ---