1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.procedure2;
20
21 import java.util.ArrayList;
22 import java.util.List;
23
24 import org.apache.commons.logging.Log;
25 import org.apache.commons.logging.LogFactory;
26 import org.apache.hadoop.hbase.classification.InterfaceAudience;
27 import org.apache.hadoop.hbase.classification.InterfaceStability;
28 import org.apache.hadoop.hbase.protobuf.generated.ProcedureProtos.ProcedureState;
29
30
31
32
33
34
35
36
37
38
39
40
41 @InterfaceAudience.Private
42 @InterfaceStability.Evolving
43 class RootProcedureState {
44 private static final Log LOG = LogFactory.getLog(RootProcedureState.class);
45
46 private enum State {
47 RUNNING,
48 FAILED,
49 ROLLINGBACK,
50 }
51
52 private ArrayList<Procedure> subprocedures = null;
53 private State state = State.RUNNING;
54 private int running = 0;
55
56 public synchronized boolean isFailed() {
57 switch (state) {
58 case ROLLINGBACK:
59 case FAILED:
60 return true;
61 default:
62 break;
63 }
64 return false;
65 }
66
67 public synchronized boolean isRollingback() {
68 return state == State.ROLLINGBACK;
69 }
70
71
72
73
74 protected synchronized boolean setRollback() {
75 if (running == 0 && state == State.FAILED) {
76 state = State.ROLLINGBACK;
77 return true;
78 }
79 return false;
80 }
81
82
83
84
85 protected synchronized void unsetRollback() {
86 assert state == State.ROLLINGBACK;
87 state = State.FAILED;
88 }
89
90 protected synchronized List<Procedure> getSubprocedures() {
91 return subprocedures;
92 }
93
94 protected synchronized RemoteProcedureException getException() {
95 if (subprocedures != null) {
96 for (Procedure proc: subprocedures) {
97 if (proc.hasException()) {
98 return proc.getException();
99 }
100 }
101 }
102 return null;
103 }
104
105
106
107
108 protected synchronized boolean acquire(final Procedure proc) {
109 if (state != State.RUNNING) return false;
110
111 running++;
112 return true;
113 }
114
115
116
117
118 protected synchronized void release(final Procedure proc) {
119 running--;
120 }
121
122 protected synchronized void abort() {
123 if (state == State.RUNNING) {
124 state = State.FAILED;
125 }
126 }
127
128
129
130
131
132 protected synchronized void addRollbackStep(final Procedure proc) {
133 if (proc.isFailed()) {
134 state = State.FAILED;
135 }
136 if (subprocedures == null) {
137 subprocedures = new ArrayList<Procedure>();
138 }
139 proc.addStackIndex(subprocedures.size());
140 subprocedures.add(proc);
141 }
142
143
144
145
146
147
148
149
150 protected synchronized void loadStack(final Procedure proc) {
151 int[] stackIndexes = proc.getStackIndexes();
152 if (stackIndexes != null) {
153 if (subprocedures == null) {
154 subprocedures = new ArrayList<Procedure>();
155 }
156 int diff = (1 + stackIndexes[stackIndexes.length - 1]) - subprocedures.size();
157 if (diff > 0) {
158 subprocedures.ensureCapacity(1 + stackIndexes[stackIndexes.length - 1]);
159 while (diff-- > 0) subprocedures.add(null);
160 }
161 for (int i = 0; i < stackIndexes.length; ++i) {
162 subprocedures.set(stackIndexes[i], proc);
163 }
164 }
165 if (proc.getState() == ProcedureState.ROLLEDBACK) {
166 state = State.ROLLINGBACK;
167 } else if (proc.isFailed()) {
168 state = State.FAILED;
169 }
170 }
171
172
173
174
175 protected synchronized boolean isValid() {
176 if (subprocedures != null) {
177 for (Procedure proc: subprocedures) {
178 if (proc == null) {
179 return false;
180 }
181 }
182 }
183 return true;
184 }
185 }