mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

boli
22.55.2009 1fbc9df5d0c44ae72c76dacc3c945d4f0d641ee6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package org.opends.sdk;
 
import com.sun.opends.sdk.util.Validator;
 
import java.util.List;
import java.util.ArrayList;
 
/**
 * Created by IntelliJ IDEA. User: digitalperk Date: Dec 15, 2009 Time: 3:49:17
 * PM To change this template use File | Settings | File Templates.
 */
public abstract class AbstractLoadBalancingAlgorithm
    implements LoadBalancingAlgorithm
{
  protected final List<MonitoredConnectionFactory> factoryList;
 
  protected AbstractLoadBalancingAlgorithm(ConnectionFactory<?>... factories)
  {
    Validator.ensureNotNull(factories);
    factoryList = new ArrayList<MonitoredConnectionFactory>(factories.length);
    for(ConnectionFactory<?> f : factories)
    {
      factoryList.add(new MonitoredConnectionFactory(f));
    }
 
    new MonitorThread().start();
  }
 
  protected class MonitoredConnectionFactory
      extends AbstractConnectionFactory<AsynchronousConnection>
      implements ResultHandler<AsynchronousConnection>
  {
    private final ConnectionFactory<?> factory;
    private volatile boolean isOperational;
    private volatile FutureResult<?> pendingConnectFuture;
 
    private MonitoredConnectionFactory(ConnectionFactory<?> factory)
    {
      this.factory = factory;
      this.isOperational = true;
    }
 
    public boolean isOperational()
    {
      return isOperational;
    }
 
    public void handleErrorResult(ErrorResultException error)
    {
      isOperational = false;
    }
 
    public void handleResult(AsynchronousConnection result)
    {
      isOperational = true;
      // TODO: Notify the server is back up
      result.close();
    }
 
    public FutureResult<? extends AsynchronousConnection>
      getAsynchronousConnection(
        final ResultHandler<? super AsynchronousConnection> resultHandler)
    {
      ResultHandler handler = new ResultHandler<AsynchronousConnection>()
      {
        public void handleErrorResult(ErrorResultException error)
        {
          isOperational = false;
          if(resultHandler != null)
          {
            resultHandler.handleErrorResult(error);
          }
        }
 
        public void handleResult(AsynchronousConnection result)
        {
          isOperational = true;
          if(resultHandler != null)
          {
            resultHandler.handleResult(result);
          }
        }
      };
      return factory.getAsynchronousConnection(handler);
    }
  }
 
  private class MonitorThread extends Thread
  {
    private MonitorThread()
    {
      super("Connection Factory Health Monitor");
      this.setDaemon(true);
    }
 
    public void run()
    {
      while(true)
      {
        for(MonitoredConnectionFactory f : factoryList)
        {
          if(!f.isOperational && (f.pendingConnectFuture == null ||
                                  f.pendingConnectFuture.isDone()))
          {
            f.pendingConnectFuture = f.factory.getAsynchronousConnection(f);
          }
        }
        try
        {
          sleep(10000);
        }
        catch (InterruptedException e)
        {
          // Ignore and just go around again...
        }
      }
    }
  }
}