class ClusterMicroserviceProvider implements MicroserviceProvider, ClusterSilverService {

   @Override
   public Set<Object> lookupMicroservice(final MicroserviceMetaData metaData) {
      try {
         Set<Address> addressesForMetadata = alreadyQueriedAddresses.getOrDefault(metaData, new HashSet<>());
         this.sender.sendToClusterAsync(metaData, addressesForMetadata,
               new FutureListenerHelper<MicroserviceSearchResponse>(rspList -> {
                  try {
                     RspList<MicroserviceSearchResponse> responseRspList = rspList.get(10, TimeUnit.SECONDS);
                     log.info("Response retrieved!  {}", responseRspList);
                     Collection<Rsp<MicroserviceSearchResponse>> result = responseRspList.values();
                     if (log.isTraceEnabled()) {
                        log.trace("Size of a responses is : {} ", responseRspList.getResults().size());
                     }
                     result.stream().filter(Rsp::hasException).forEach(rsp -> log.error("Exception was thrown during lookup on node: " + rsp.getSender(), rsp.getException()));

                     Set<ServiceHandle> remoteServiceHandles = result.stream()
                                                                     .filter(rsp -> rsp.wasReceived() && !rsp.hasException() && rsp.getValue().getResult().canBeUsed())
                                                                     .map((rsp) -> new RemoteServiceHandle(rsp.getSender(), rsp.getValue().getHandle(), sender, metaData))
                                                                     .collect(Collectors.toSet());
                     // this is to save jgroups traffic for a given metadata
                     addressesForMetadata.addAll(responseRspList.values().stream().map(Rsp::getSender).collect(Collectors.toSet()));
                     alreadyQueriedAddresses.put(metaData, addressesForMetadata);
                     this.remoteServiceHandlesStore.addHandles(metaData, remoteServiceHandles);
                  } catch (Throwable e) {
                     log.error("Error while looking up microservices.", e);
                  }

               }));
         // If this is first query for the metadata we should wait for a response
         if (addressesForMetadata.isEmpty() && !sender.isEmptyCluster()) {
            Thread.sleep(timeout);
         }

         return this.remoteServiceHandlesStore.getServices(metaData);
      } catch (Throwable e) {
         log.error("Error while looking up microservices.", e);
         return emptySet();
      }
   }

}