View Javadoc

1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.jspf.impl;
21  
22  import org.apache.james.jspf.core.DNSRequest;
23  import org.apache.james.jspf.core.DNSService;
24  import org.apache.james.jspf.core.exceptions.TimeoutException;
25  import org.apache.james.jspf.executor.DNSAsynchLookupService;
26  import org.apache.james.jspf.executor.IResponseImpl;
27  import org.apache.james.jspf.executor.IResponseQueue;
28  
29  import java.util.LinkedList;
30  
31  /**
32   * Wrap a DNSService an execute the calls asynch in a new Thread
33   */
34  public class DNSServiceAsynchSimulator implements Runnable, DNSAsynchLookupService {
35  
36      private DNSService dnsService;
37      private Thread worker;
38      private LinkedList queue;
39      private int waitingThreads = 0;
40      private boolean multiThread;
41      
42      private static final class Request {
43          private final DNSRequest value;
44          private final Object id;
45          private final IResponseQueue responseQueue;
46          public Request(DNSRequest value, Object id, IResponseQueue responseQueue) {
47              this.value = value;
48              this.id = id;
49              this.responseQueue = responseQueue;
50          }
51          public DNSRequest getValue() {
52              return value;
53          }
54          public Object getId() {
55              return id;
56          }
57          public IResponseQueue getResponseQueue() {
58              return responseQueue;
59          }
60          
61      }
62  
63      public DNSServiceAsynchSimulator(DNSService service, boolean multiThread) {
64          this.dnsService = service;
65          this.multiThread = multiThread;
66  
67          this.queue = new LinkedList();
68          this.worker = new Thread(this);
69          this.worker.setDaemon(true);
70          this.worker.setName("DNSServiceAsynchSimulator");
71          this.worker.start();
72  
73      }
74  
75      /**
76       * @see org.apache.james.jspf.executor.DNSAsynchLookupService#getRecordsAsynch(org.apache.james.jspf.core.DNSRequest, int, org.apache.james.jspf.executor.IResponseQueue)
77       */
78      public void getRecordsAsynch(DNSRequest request, int id,
79              final IResponseQueue responsePool) {
80          
81          synchronized (queue) {
82              queue.addLast(new Request(request, new Integer(id), responsePool));
83              queue.notify();
84          }
85          
86      }
87  
88      /**
89       * Run the async dns call in a new thread
90       */
91      public void run() {
92          while (true) {
93              Request req;
94              synchronized (queue) {
95                  if ( (queue.size() - waitingThreads <= 0) ) {
96                      try {
97                          waitingThreads++; queue.wait();
98                      } catch (InterruptedException e) {
99                          Thread.interrupted();
100                     }
101                     waitingThreads--;
102                 }
103                 req = (Request) queue.removeFirst();
104             }
105             
106             Runnable runnable = new Runnable() {
107 
108                 private Request req;
109 
110                 public void run() {
111                     IResponseImpl response;
112                     try {
113                         response = new IResponseImpl(req.getId(), dnsService.getRecords(req.getValue()));
114                     } catch (TimeoutException e) {
115                         response = new IResponseImpl(req.getId(), e);
116                     }
117 
118                     req.getResponseQueue().insertResponse(response);
119                 }
120 
121                 public Runnable setRequest(Request req) {
122                     this.req = req;
123                     return this;
124                 }
125                 
126             }.setRequest(req);
127             
128             if (multiThread) {
129                 new Thread(runnable).start();
130             } else {
131                 runnable.run();
132             }
133         }
134     }
135 
136 }