KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jgroups > blocks > TwoPhaseVotingAdapter


1 package org.jgroups.blocks;
2
3 import org.jgroups.ChannelException;
4
5 /**
6  * This adapter introduces simple two-phase voting on a specified decree. All
7  * nodes in the group receive a decree in "prepare" phase where they expres
8  * their opinion on the decree. If all nodes voted positively on decree, next
9  * phase "commit" fixes changes that were made in "prepare" phase, otherwise
10  * changes are canceled in "abort" phase.
11  *
12  * @author Roman Rokytskyy (rrokytskyy@acm.org)
13  */

14 public class TwoPhaseVotingAdapter {
15
16     private final VotingAdapter voteChannel;
17
18     /**
19      * Creats an instance of the class.
20      * @param voteChannel the channel that will be used for voting.
21      */

22     public TwoPhaseVotingAdapter(VotingAdapter voteChannel) {
23         this.voteChannel = voteChannel;
24     }
25
26     /**
27      * Wraps actual listener with the VoteChannelListener and adds to the
28      * voteChannel
29      */

30     public void addListener(TwoPhaseVotingListener listener) {
31         voteChannel.addVoteListener(new TwoPhaseVoteWrapper(listener));
32     }
33
34     /**
35      * Removes the listener from the voteChannel
36      */

37     public void removeListener(TwoPhaseVotingListener listener) {
38         voteChannel.removeVoteListener(new TwoPhaseVoteWrapper(listener));
39     }
40
41     /**
42      * Performs the two-phase voting on the decree. After the voting each
43      * group member remains in the same state as others.
44      */

45     public boolean vote(Object JavaDoc decree, long timeout) throws ChannelException {
46         // wrap real decree
47
TwoPhaseWrapper wrappedDecree = new TwoPhaseWrapper(decree);
48
49         // check the decree acceptance
50
try {
51             if (voteChannel.vote(wrappedDecree, timeout / 3)) {
52                 wrappedDecree.commit();
53
54                 // try to commit decree
55
if (!voteChannel.vote(wrappedDecree, timeout / 3)) {
56                     // strange, should fail during prepare... abort all
57
wrappedDecree.abort();
58                     voteChannel.vote(wrappedDecree, timeout / 3);
59                     return false;
60                 } else
61                         return true;
62
63             } else {
64                 // somebody is not accepting the decree... abort
65
wrappedDecree.abort();
66                 voteChannel.vote(wrappedDecree, timeout / 3);
67                 return false;
68             }
69         } catch(ChannelException chex) {
70             wrappedDecree.abort();
71             voteChannel.vote(wrappedDecree, timeout / 3 );
72             throw chex;
73         }
74     }
75  
76     public static class TwoPhaseVoteWrapper implements VotingListener {
77     
78         private final TwoPhaseVotingListener listener;
79     
80         public TwoPhaseVoteWrapper(TwoPhaseVotingListener listener) {
81             this.listener = listener;
82         }
83     
84         public boolean vote(Object JavaDoc decree) throws VoteException {
85             if (!(decree instanceof TwoPhaseWrapper))
86                 throw new VoteException("Not my type of decree. Ignore me.");
87     
88             TwoPhaseWrapper wrapper = (TwoPhaseWrapper)decree;
89     
90             // invoke the corresponding operation
91
if (wrapper.isPrepare())
92                 return listener.prepare(wrapper.getDecree());
93             else
94             if (wrapper.isCommit())
95                 return listener.commit(wrapper.getDecree());
96             else {
97                 listener.abort(wrapper.getDecree());
98                 return false;
99             }
100         }
101     
102         /*
103     
104          This wrapper is completely equal to the object it wraps.
105     
106          Therefore the hashCode():int and equals(Object):boolean are
107          simply delegated to the wrapped code.
108     
109          */

110     
111         public int hashCode() { return listener.hashCode(); }
112         public boolean equals(Object JavaDoc other) { return listener.equals(other); }
113     }
114
115     /**
116      * Wrapper of the decree to voting decree.
117      */

118     public static class TwoPhaseWrapper implements java.io.Serializable JavaDoc {
119         private static final int PREPARE = 0;
120         private static final int COMMIT = 1;
121         private static final int ABORT = 2;
122     
123         public TwoPhaseWrapper(Object JavaDoc decree) {
124             setDecree(decree);
125             setType(PREPARE);
126         }
127     
128         private Object JavaDoc decree;
129         private int type;
130     
131         public Object JavaDoc getDecree(){ return decree; }
132         public void setDecree(Object JavaDoc decree){ this.decree = decree; }
133     
134         private int getType() { return type; }
135         private void setType(int type) { this.type = type; }
136         private boolean isType(int type) { return this.type == type; }
137     
138         public boolean isPrepare() { return isType(PREPARE); }
139         public boolean isCommit() { return isType(COMMIT); }
140         public boolean isAbort() { return isType(ABORT); }
141     
142         public void commit() { setType(COMMIT); }
143         public void abort() { setType(ABORT); }
144     
145         public String JavaDoc toString() { return decree.toString(); }
146     }
147 }
Popular Tags