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

boli
22.37.2009 9d6f5c9a5b7771e595892e6935cf1cc42012c4c6
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package org.opends.sdk;
 
import com.sun.opends.sdk.util.Validator;
import com.sun.opends.sdk.util.StaticUtils;
 
import java.util.List;
import java.util.ArrayList;
import java.util.logging.Level;
 
/**
 * 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);
          }
          if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
          {
            StaticUtils.DEBUG_LOG
                .warning(String
                    .format(
                    "Connection factory " + factory +
                        " is no longer operational: "
                        + error.getMessage()));
          }
        }
 
        public void handleResult(AsynchronousConnection result)
        {
          isOperational = true;
          if(resultHandler != null)
          {
            resultHandler.handleResult(result);
          }
          if (StaticUtils.DEBUG_LOG.isLoggable(Level.WARNING))
          {
            StaticUtils.DEBUG_LOG
                .warning(String
                    .format(
                    "Connection factory " + factory +
                        " is now operational"));
          }
        }
      };
      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()))
          {
            if (StaticUtils.DEBUG_LOG.isLoggable(Level.FINEST))
            {
              StaticUtils.DEBUG_LOG
                  .finest(String.format("Attempting connect on factory " + f));
            }
            f.pendingConnectFuture = f.factory.getAsynchronousConnection(f);
          }
        }
        try
        {
          sleep(10000);
        }
        catch (InterruptedException e)
        {
          // Ignore and just go around again...
        }
      }
    }
  }
}