All Downloads are FREE. Search and download functionalities are using the official Maven repository.

convex.peer.QueryHandler Maven / Gradle / Ivy

package convex.peer;

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import convex.core.Result;
import convex.core.ResultContext;
import convex.core.SourceCodes;
import convex.core.data.ACell;
import convex.core.data.AVector;
import convex.core.data.Address;
import convex.core.data.prim.CVMLong;
import convex.core.lang.RT;
import convex.core.util.LoadMonitor;
import convex.net.Message;
import convex.net.MessageType;

public class QueryHandler extends AThreadedComponent {

	private static final Logger log = LoggerFactory.getLogger(QueryHandler.class.getName());

	/**
	 * Queue for received messages to be processed by this Peer Server
	 */
	private ArrayBlockingQueue queryQueue = new ArrayBlockingQueue(Config.QUERY_QUEUE_SIZE);

	public QueryHandler(Server server) {
		super(server);	
		queryQueue= new ArrayBlockingQueue<>(Config.TRANSACTION_QUEUE_SIZE);
	}
	
	/**
	 * Offer a transaction for handling
	 * @param m Message offered
	 * @return True if queued for handling, false otherwise
	 */
	public boolean offerQuery(Message m) {
		return queryQueue.offer(m);
	}
	

	@Override
	protected void loop() throws InterruptedException {
		LoadMonitor.down();
		Message m = queryQueue.poll(10000, TimeUnit.MILLISECONDS);
		LoadMonitor.up();
		if (m==null) return;
		
		MessageType type=m.getType();
		switch (type) {
		case QUERY:
			handleQuery(m);
			break;
		case REQUEST_DATA:
			server.handleDataRequest(m);
			break;
		default:
			log.warn("Unexpected Message type on query queue: "+type);
		}
	}
	
	private void handleQuery(Message m) {
		try {
			// query is a vector [id , form, address?]
			AVector v= m.getPayload();
			CVMLong id = (CVMLong) v.get(0);
			ACell form = v.get(1);
	
			// extract the Address, might be null
			Address address = RT.ensureAddress(v.get(2));
	
			log.debug( "Processing query: {} with address: {}" , form, address);
			// log.log(LEVEL_MESSAGE, "Processing query: " + form + " with address: " +
			// address);
			
			// Return result
			ResultContext resultContext = server.getPeer().executeQuery(form, address);
			Result result=Result.fromContext(id, resultContext).withSource(SourceCodes.PEER);
			
			// Report result back to message sender
			boolean resultReturned= m.returnResult(result);
	
			if (!resultReturned) {
				log.warn("Failed to send query result back to client with ID: {}", id);
			}
		} catch (Exception e) {
			log.debug("Terminated client: "+e.getMessage());
			m.closeConnection();
		}

	}

	@Override
	protected String getThreadName() {
		return "Query handler on port: " + server.getPort();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy