1 package hudson.remoting; 2 3 import java.io.IOException ; 4 import java.io.Serializable ; 5 import java.util.concurrent.ExecutionException ; 6 import java.util.concurrent.TimeUnit ; 7 import java.util.concurrent.TimeoutException ; 8 import java.util.logging.Level ; 9 import java.util.logging.Logger ; 10 11 21 abstract class Request<RSP extends Serializable ,EXC extends Throwable > extends Command { 22 23 36 protected abstract RSP perform(Channel channel) throws EXC; 37 38 42 private final int id; 43 44 private volatile Response<RSP,EXC> response; 45 46 protected Request() { 47 synchronized(Request.class) { 48 id = nextId++; 49 } 50 } 51 52 66 public final RSP call(Channel channel) throws EXC, InterruptedException , IOException { 67 synchronized(channel) { 71 synchronized(this) { 72 response=null; 73 74 channel.pendingCalls.put(id,this); 75 channel.send(this); 76 } 77 } 78 79 synchronized(this) { 80 while(response==null) 81 wait(); 83 Object exc = response.exception; 84 85 if(exc !=null) 86 throw (EXC)exc; 88 return response.returnValue; 89 } 90 } 91 92 103 public final Future<RSP> callAsync(Channel channel) throws IOException { 104 response=null; 105 106 channel.pendingCalls.put(id,this); 107 channel.send(this); 108 109 return new Future<RSP>() { 110 113 public boolean cancel(boolean mayInterruptIfRunning) { 114 return false; 115 } 116 117 public boolean isCancelled() { 118 return false; 119 } 120 121 public boolean isDone() { 122 return response!=null; 123 } 124 125 public RSP get() throws InterruptedException , ExecutionException { 126 synchronized(Request.this) { 127 while(response==null) 128 Request.this.wait(); 130 if(response.exception!=null) 131 throw new ExecutionException (response.exception); 132 133 return response.returnValue; 134 } 135 } 136 137 public RSP get(long timeout, TimeUnit unit) throws InterruptedException , ExecutionException , TimeoutException { 138 synchronized(Request.this) { 139 if(response==null) 140 Request.this.wait(unit.toMillis(timeout)); if(response==null) 142 throw new TimeoutException (); 143 144 if(response.exception!=null) 145 throw new ExecutionException (response.exception); 146 147 return response.returnValue; 148 } 149 } 150 }; 151 } 152 153 154 157 synchronized void onCompleted(Response<RSP,EXC> response) { 158 this.response = response; 159 notify(); 160 } 161 162 165 void abort(IOException e) { 166 onCompleted(new Response(id,new RequestAbortedException(e))); 167 } 168 169 172 protected final void execute(final Channel channel) { 173 channel.executor.execute(new Runnable () { 174 public void run() { 175 try { 176 RSP rsp; 177 try { 178 rsp = Request.this.perform(channel); 179 } catch (Throwable t) { 180 channel.send(new Response<RSP,Throwable >(id,t)); 182 return; 183 } 184 channel.send(new Response<RSP,EXC>(id,rsp)); 186 } catch (IOException e) { 187 logger.log(Level.SEVERE, "Failed to send back a reply",e); 190 } 191 } 192 }); 193 } 194 195 198 private static int nextId=0; 199 200 private static final long serialVersionUID = 1L; 201 202 private static final Logger logger = Logger.getLogger(Request.class.getName()); 203 204 206 } 218 | Popular Tags |