/* * Copyright (c) 2013 Websquared, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v2.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html * * Contributors: * swsong - initial API and implementation */ package org.fastcatsearch.control; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class ResultFuture { private static Logger logger = LoggerFactory.getLogger(ResultFuture.class); protected BlockingQueue<Object> queue; protected boolean isSuccess; protected long requestId; protected Map<Long, ? extends ResultFuture> resultFutureMap; protected long startTime; protected Object result; private static NullResult NULL_RESULT = new NullResult(); private static class NullResult { } /** * 실패 결과. * */ public ResultFuture() { requestId = -1; result = NULL_RESULT; } public ResultFuture(long requestId, Map<Long, ? extends ResultFuture> resultFutureMap) { this.requestId = requestId; this.resultFutureMap = resultFutureMap; this.startTime = System.currentTimeMillis(); queue = new LinkedBlockingQueue<Object>(); } public long getElapsedTimeMilis(){ return System.currentTimeMillis() - startTime; } public void putNullFail() { this.isSuccess = false; try { queue.put(NULL_RESULT); } catch (InterruptedException ignore) { } } public void put(Object result, boolean isSuccess) { this.isSuccess = isSuccess; try { if(result == null){ queue.put(NULL_RESULT); }else{ queue.put(result); } } catch (InterruptedException ignore) { } } public boolean isSuccess(){ return isSuccess; } public Object get(){ return result; } public Object take() { if(result != null){ if(result == NULL_RESULT){ return null; }else{ return result; } } try { result = queue.take(); if(result == NULL_RESULT){ return null; } return result; } catch (InterruptedException e) { //결과를 받지 못할경우, map에서 제거해준다. resultFutureMap.remove(requestId); return null; } } public Object poll(int timeInSecond) { if(result != null){ if(result == NULL_RESULT){ return null; }else{ return result; } } long remainMilisecondTime = timeInSecond * 1000 - (System.currentTimeMillis() - startTime); try { if(remainMilisecondTime > 0){ Object result = queue.poll(remainMilisecondTime, TimeUnit.MILLISECONDS); if(result == null){ //결과가 아직도착하지 않아서 받지못하거나, 네트워크 문제로 인해 전달이 안될수도 있으므로 불필요한 객체를 map에서 제거한다. resultFutureMap.remove(requestId); }else if(result == NULL_RESULT){ return null; } return result; }else{ Object result = queue.poll(); if(result == null){ //시간초과에 따른 제거일수도 있으므로, resultFutureMap.remove(requestId); }else if(result == NULL_RESULT){ return null; } return result; } } catch (InterruptedException e) { resultFutureMap.remove(requestId); return null; } } }