KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > ha > framework > server > HATarget


1 /*
2   * JBoss, Home of Professional Open Source
3   * Copyright 2005, JBoss Inc., and individual contributors as indicated
4   * by the @authors tag. See the copyright.txt in the distribution for a
5   * full listing of individual contributors.
6   *
7   * This is free software; you can redistribute it and/or modify it
8   * under the terms of the GNU Lesser General Public License as
9   * published by the Free Software Foundation; either version 2.1 of
10   * the License, or (at your option) any later version.
11   *
12   * This software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15   * Lesser General Public License for more details.
16   *
17   * You should have received a copy of the GNU Lesser General Public
18   * License along with this software; if not, write to the Free
19   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21   */

22 package org.jboss.ha.framework.server;
23
24 import java.util.ArrayList JavaDoc;
25 import java.util.List JavaDoc;
26 import org.jboss.ha.framework.interfaces.DistributedReplicantManager;
27 import org.jboss.ha.framework.interfaces.DistributedReplicantManager.ReplicantListener;
28 import org.jboss.ha.framework.interfaces.HAPartition;
29 import java.io.Serializable JavaDoc;
30 import EDU.oswego.cs.dl.util.concurrent.Latch;
31
32 /**
33  * This class is a holder and manager of replicants.
34  * It manages lists of replicated objects and changes the list as the HAPartition
35  * notifies it.
36  *
37  * @author bill@burkecentral.com
38  * @version $Revision: 39164 $
39  *
40  * <p><b>Revisions:</b><br>
41  * <p><b>2002/01/13: Bill Burke</b>
42  * <ol>
43  * <li>Initial revision
44  * </ol>
45  */

46 public class HATarget
47    implements ReplicantListener
48 {
49    public static final int DISABLE_INVOCATIONS = 0;
50    public static final int MAKE_INVOCATIONS_WAIT = 1;
51    public static final int ENABLE_INVOCATIONS = 2;
52    
53    protected String JavaDoc replicantName;
54    protected ArrayList JavaDoc replicants = new ArrayList JavaDoc();
55    protected HAPartition partition = null;
56    protected org.jboss.logging.Logger log;
57    protected int clusterViewId = 0;
58    protected Serializable JavaDoc target;
59    protected int allowInvocationsStatus = 0;
60    protected Latch latch = null;
61    
62    public HATarget(HAPartition partition,
63            String JavaDoc replicantName,
64            Serializable JavaDoc target,
65          int allowInvocations)
66       throws Exception JavaDoc
67    {
68       this.replicantName = replicantName;
69       this.target = target;
70       init ();
71       setInvocationsAuthorization (allowInvocations);
72       updateHAPartition(partition);
73    }
74    
75    public void init() throws Exception JavaDoc
76    {
77       this.log = org.jboss.logging.Logger.getLogger(this.getClass());
78    }
79
80    public String JavaDoc toString()
81    {
82       StringBuffer JavaDoc buffer = new StringBuffer JavaDoc(super.toString());
83       buffer.append('{');
84       buffer.append("replicantName="+replicantName);
85       buffer.append("partition="+partition.getPartitionName());
86       buffer.append("clusterViewId="+clusterViewId);
87       buffer.append("allowInvocationsStatus="+allowInvocationsStatus);
88       buffer.append("replicants="+replicants);
89       buffer.append('}');
90       return buffer.toString();
91    }
92
93    public long getCurrentViewId()
94    {
95       return (long)clusterViewId;
96    }
97    
98    public void destroy()
99    {
100       try
101       {
102          this.cleanExistenceInCurrentHAPartition();
103          
104          // maybe some threads are blocked: we let them go here:
105
//
106
setInvocationsAuthorization (HATarget.DISABLE_INVOCATIONS);
107       }
108       catch (Exception JavaDoc e)
109       {
110          log.error("failed to destroy", e);
111       }
112    }
113  
114    // After this call, the HATarget can still be queried for view change, etc. but
115
// the local node is no more part of the cluster: temporary state
116
//
117
public void disable()
118    {
119       try
120       {
121          if (this.partition != null)
122          {
123             log.debug ("Disabled called on HATarget");
124             this.partition.getDistributedReplicantManager().remove (this.replicantName);
125          }
126       }
127       catch (Exception JavaDoc e)
128       {
129          log.error("failed to disable", e);
130       }
131    }
132    
133    public ArrayList JavaDoc getReplicants()
134    {
135       return replicants;
136    }
137    
138    public void updateHAPartition(HAPartition partition) throws Exception JavaDoc
139    {
140       cleanExistenceInCurrentHAPartition();
141       
142       this.partition = partition;
143       DistributedReplicantManager drm = partition.getDistributedReplicantManager();
144       drm.registerListener(this.replicantName, this);
145       drm.add(this.replicantName, this.target);
146    }
147
148    public synchronized void setInvocationsAuthorization (int status)
149    {
150       if (this.allowInvocationsStatus == status)
151       {
152          // we don't release and reget a latch if two identical calls are performed
153
//
154
log.debug ("Invocation authorization called with no-op");
155       }
156       else
157       {
158          // CRITICAL CODE! DONT CHANGE ORDER WITHOUT THINKING ABOUT RACE CONDITIONS
159
//
160
if (status == MAKE_INVOCATIONS_WAIT)
161          {
162             log.debug ("Invocation authorization called: MAKE_INVOCATIONS_WAIT");
163             latch = new Latch();
164             this.allowInvocationsStatus = status;
165          }
166          else
167          {
168             log.debug ("Invocation authorization called: " +
169                ((status==ENABLE_INVOCATIONS)?"ENABLE_INVOCATIONS":"DISABLE_INVOCATIONS") );
170             this.allowInvocationsStatus = status;
171             if (latch != null)
172                latch.release();
173          }
174       }
175    }
176    
177    public boolean invocationsAllowed () throws InterruptedException JavaDoc
178    {
179       if (this.allowInvocationsStatus == ENABLE_INVOCATIONS)
180          return true;
181       else if (this.allowInvocationsStatus == DISABLE_INVOCATIONS)
182          return false;
183       else if (this.allowInvocationsStatus == MAKE_INVOCATIONS_WAIT)
184       {
185          latch.acquire ();
186          
187          // if we arrive here, it means that the status has been changed, so
188
// we check for the decision:
189
//
190
if (this.allowInvocationsStatus == ENABLE_INVOCATIONS)
191             return true;
192          else
193             return false;
194       }
195       else
196          return false;
197    }
198    
199    protected void releaseCurrentLatch ()
200    {
201       latch.release ();
202       latch = null;
203    }
204    
205    public HAPartition getAssociatedPartition ()
206    {
207        return this.partition;
208    }
209    
210    // DistributedReplicantManager.ReplicantListener implementation ------------
211

212    public void replicantsChanged(String JavaDoc key, List JavaDoc newReplicants, int newReplicantsViewId)
213    {
214       if (log.isDebugEnabled())
215          log.debug("replicantsChanged '" + replicantName +
216                    "' to " + (newReplicants==null? "0 (null)" : Integer.toString (newReplicants.size() ) ) +
217                    " (intra-view id: " + newReplicantsViewId + ")");
218       
219       synchronized(replicants)
220       {
221          // client has reference to replicants so it will automatically get
222
// updated
223
replicants.clear();
224          if (newReplicants != null)
225             replicants.addAll(newReplicants);
226          
227          this.clusterViewId = newReplicantsViewId;
228       }
229       
230    }
231    
232    protected void cleanExistenceInCurrentHAPartition()
233    {
234       if (this.partition != null)
235       {
236          try
237          {
238             DistributedReplicantManager drm = partition.getDistributedReplicantManager();
239             drm.unregisterListener(this.replicantName, this);
240             drm.remove(this.replicantName);
241          }
242          catch (Exception JavaDoc e)
243          {
244             log.error("failed to clean existence in current ha partition", e);
245          }
246       }
247    }
248 }
249
Popular Tags