private void executeReadRequestOnReadQuorum(
			HashMap<Machine, String> responseMap,
			HashSet<Machine> successfulServers, HashSet<Machine> failedServers,
			int articleReadFrom) {

		if (failedServers != null) {
			if (failedServers.contains(myInfo)) {
				/*
				 * if the failedServers contain myMachine then I am a backup and
				 * hence I am always upto date
				 */
				logger.info("As my machine is the readSet, I am backup and hence no need to sync;myInfo="
						+ myInfo);
				failedServers.clear();
			} else {
				List<ReadService> threadsToRead = new ArrayList<ReadService>(
						failedServers.size());
				final CountDownLatch readQuorumlatch = new CountDownLatch(
						failedServers.size());

				for (Machine server : failedServers) {
					ReadService t = new ReadService(server, readQuorumlatch,
							articleReadFrom);
					threadsToRead.add(t);
					t.start();
				}
				try {
					if (!readQuorumlatch.await(Props.NETWORK_TIMEOUT,
							TimeUnit.MILLISECONDS)) {
						interruptReadThreads(threadsToRead);
					}

					for (ReadService rs : threadsToRead) {
						String str = null;

						str = Utils.byteToString(rs.dataRead, Props.ENCODING);
						responseMap.put(rs.serverToRead, str);

					}
				} catch (InterruptedException ie) {
					logger.error("Error", ie);
					// interrupt all other threads
					// TODO other servers should kill
					interruptReadThreads(threadsToRead);
				} finally {
					// if not thread has some value add it to the success
					// servers
					// else let
					// it be in failed set
					for (ReadService rs : threadsToRead) {
						if (rs.dataRead != null) {
							successfulServers.add(rs.serverToRead);
							failedServers.remove(rs.serverToRead);
						}
					}
				}

			}

		}
	}