From f342b47d62579e83a04b56cf86a8427909b3cc4d Mon Sep 17 00:00:00 2001 From: zyxxoo <1318247699@qq.com> Date: Tue, 16 Aug 2022 16:41:01 +0800 Subject: [PATCH] improve code --- .../com/baidu/hugegraph/election/Config.java | 19 +++ .../baidu/hugegraph/election/MetaData.java | 66 ---------- .../hugegraph/election/MetaDataAdapter.java | 12 -- .../election/RoleElectionStateMachine.java | 19 +++ .../RoleElectionStateMachineImpl.java | 121 ++++++++++-------- .../election/RoleStataDataAdapter.java | 31 +++++ .../hugegraph/election/RoleStateData.java | 91 +++++++++++++ .../election/StateMachineCallback.java | 19 +++ .../election/StateMachineContext.java | 21 ++- .../core/RoleElectionStateMachineTest.java | 57 ++++++--- 10 files changed, 308 insertions(+), 148 deletions(-) delete mode 100644 hugegraph-core/src/main/java/com/baidu/hugegraph/election/MetaData.java delete mode 100644 hugegraph-core/src/main/java/com/baidu/hugegraph/election/MetaDataAdapter.java create mode 100644 hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleStataDataAdapter.java create mode 100644 hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleStateData.java diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/Config.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/Config.java index e85658f3a6..ad39c0b5ef 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/Config.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/Config.java @@ -1,3 +1,22 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + package com.baidu.hugegraph.election; public interface Config { diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/MetaData.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/MetaData.java deleted file mode 100644 index e42b571543..0000000000 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/MetaData.java +++ /dev/null @@ -1,66 +0,0 @@ -package com.baidu.hugegraph.election; - -import java.util.Objects; - -public class MetaData { - - String node; - long count; - int epoch; - - public MetaData(String node, int epoch) { - this(node, epoch, 1); - } - - public MetaData(String node, int epoch, long count) { - this.node = node; - this.epoch = epoch; - this.count = count; - } - - public void increaseCount() { - this.count++; - } - - public boolean isMaster(String node) { - return Objects.equals(this.node, node); - } - - public int epoch() { - return this.epoch; - } - - public long count() { - return this.count; - } - - public void count(long count) { - this.count = count; - } - - public String node() { - return this.node; - } - - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof MetaData)) return false; - MetaData metaData = (MetaData) o; - return count == metaData.count && epoch == metaData.epoch && Objects.equals(node, metaData.node); - } - - @Override - public int hashCode() { - return Objects.hash(node, count, epoch); - } - - @Override - public String toString() { - return "MetaData{" + - "node='" + node + '\'' + - ", count=" + count + - ", epoch=" + epoch + - '}'; - } -} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/MetaDataAdapter.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/MetaDataAdapter.java deleted file mode 100644 index 196183bb76..0000000000 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/MetaDataAdapter.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.baidu.hugegraph.election; - -import java.util.Optional; - -public interface MetaDataAdapter { - - boolean postDelyIfPresent(MetaData metaData, long delySecond); - - Optional queryDelay(long delySecond); - - Optional query(); -} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleElectionStateMachine.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleElectionStateMachine.java index 51933a93d7..4bc258623b 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleElectionStateMachine.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleElectionStateMachine.java @@ -1,3 +1,22 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + package com.baidu.hugegraph.election; public interface RoleElectionStateMachine { diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleElectionStateMachineImpl.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleElectionStateMachineImpl.java index d79c1c0d0b..ffb535d233 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleElectionStateMachineImpl.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleElectionStateMachineImpl.java @@ -1,3 +1,22 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + package com.baidu.hugegraph.election; import java.security.SecureRandom; @@ -9,15 +28,13 @@ public class RoleElectionStateMachineImpl implements RoleElectionStateMachine { private volatile boolean shutdown = false; - private Config config; - + private final Config config; private volatile RoleState state; + private final RoleStataDataAdapter roleStataDataAdapter; - private final MetaDataAdapter metaDataAdapter; - - public RoleElectionStateMachineImpl(Config config, MetaDataAdapter adapter) { + public RoleElectionStateMachineImpl(Config config, RoleStataDataAdapter adapter) { this.config = config; - this.metaDataAdapter = adapter; + this.roleStataDataAdapter = adapter; this.state = new UnKnownState(null); } @@ -78,7 +95,7 @@ private interface Callback { private static class UnKnownState implements RoleState { - Integer epoch; + final Integer epoch; public UnKnownState(Integer epoch) { this.epoch = epoch; @@ -86,28 +103,28 @@ public UnKnownState(Integer epoch) { @Override public RoleState transform(StateMachineContext context) { - MetaDataAdapter adapter = context.adapter(); - Optional metaDataOpt = adapter.query(); - if (!metaDataOpt.isPresent()) { + RoleStataDataAdapter adapter = context.adapter(); + Optional stateDataOpt = adapter.query(); + if (!stateDataOpt.isPresent()) { context.reset(); - this.epoch = this.epoch == null ? 1 : this.epoch + 1; - context.epoch(this.epoch); - return new CandidateState(this.epoch); + Integer nextEpoch = this.epoch == null ? 1 : this.epoch + 1; + context.epoch(nextEpoch); + return new CandidateState(nextEpoch); } - MetaData metaData = metaDataOpt.get(); - if (this.epoch != null && metaData.epoch() < this.epoch) { + RoleStateData stateData = stateDataOpt.get(); + if (this.epoch != null && stateData.epoch() < this.epoch) { context.reset(); - this.epoch = this.epoch == null ? 1 : this.epoch + 1; - context.epoch(this.epoch); - return new CandidateState(this.epoch); + Integer nextEpoch = this.epoch + 1; + context.epoch(nextEpoch); + return new CandidateState(nextEpoch); } - context.epoch(metaData.epoch()); - if (metaData.isMaster(context.node())) { - return new MasterState(metaData); + context.epoch(stateData.epoch()); + if (stateData.isMaster(context.node())) { + return new MasterState(stateData); } else { - return new WorkerState(metaData); + return new WorkerState(stateData); } } @@ -119,7 +136,7 @@ public Callback callback(StateMachineCallback callback) { private static class SafeState implements RoleState { - Integer epoch; + private final Integer epoch; public SafeState(Integer epoch) { this.epoch = epoch; @@ -139,22 +156,22 @@ public Callback callback(StateMachineCallback callback) { private static class MasterState implements RoleState { - MetaData metaData; + private final RoleStateData stateData; - public MasterState(MetaData metaData) { - this.metaData = metaData; + public MasterState(RoleStateData stateData) { + this.stateData = stateData; } @Override public RoleState transform(StateMachineContext context) { - this.metaData.increaseCount(); + this.stateData.increaseCount(); RoleState.heartBeatPark(context); - if (context.adapter().postDelyIfPresent(this.metaData, -1)) { + if (context.adapter().delayIfNodePresent(this.stateData, -1)) { return this; } context.reset(); - context.epoch(this.metaData.epoch()); - return new UnKnownState(this.metaData.epoch()).transform(context); + context.epoch(this.stateData.epoch()); + return new UnKnownState(this.stateData.epoch()).transform(context); } @Override @@ -165,21 +182,21 @@ public Callback callback(StateMachineCallback callback) { private static class WorkerState implements RoleState { - private MetaData metaData; + private RoleStateData stateData; private int count = 0; - public WorkerState(MetaData metaData) { - this.metaData = metaData; + public WorkerState(RoleStateData stateData) { + this.stateData = stateData; } @Override public RoleState transform(StateMachineContext context) { RoleState.heartBeatPark(context); - RoleState nextState = new UnKnownState(this.metaData.epoch()).transform(context); + RoleState nextState = new UnKnownState(this.stateData.epoch()).transform(context); if (nextState instanceof WorkerState) { this.merge((WorkerState) nextState); if (this.count > context.config().exceedsWorkerCount()) { - return new CandidateState(this.metaData.epoch() + 1); + return new CandidateState(this.stateData.epoch() + 1); } else { return this; } @@ -194,18 +211,18 @@ public Callback callback(StateMachineCallback callback) { } public void merge(WorkerState state) { - if (state.metaData.epoch() > this.metaData.epoch()) { + if (state.stateData.epoch() > this.stateData.epoch()) { this.count = 0; - this.metaData = state.metaData; - } else if (state.metaData.epoch() < this.metaData.epoch()){ + this.stateData = state.stateData; + } else if (state.stateData.epoch() < this.stateData.epoch()){ throw new IllegalStateException("Epoch must increase"); - } else if (state.metaData.epoch() == this.metaData.epoch() && - state.metaData.count() < this.metaData.count()) { + } else if (state.stateData.epoch() == this.stateData.epoch() && + state.stateData.count() < this.stateData.count()) { throw new IllegalStateException("Meta count must increase"); - } else if (state.metaData.epoch() == this.metaData.epoch() && - state.metaData.count() > this.metaData.count()) { + } else if (state.stateData.epoch() == this.stateData.epoch() && + state.stateData.count() > this.stateData.count()) { this.count = 0; - this.metaData = state.metaData; + this.stateData = state.stateData; } else { this.count++; } @@ -214,7 +231,7 @@ public void merge(WorkerState state) { private static class CandidateState implements RoleState { - Integer epoch; + private final Integer epoch; public CandidateState(Integer epoch) { this.epoch = epoch; @@ -224,13 +241,13 @@ public CandidateState(Integer epoch) { public RoleState transform(StateMachineContext context) { RoleState.randomPark(context); int epoch = this.epoch == null ? 1 : this.epoch; - MetaData metaData = new MetaData(context.config().node(), epoch); + RoleStateData stateData = new RoleStateData(context.config().node(), epoch); //failover to master success - context.epoch(metaData.epoch()); - if (context.adapter().postDelyIfPresent(metaData, -1)) { - return new MasterState(metaData); + context.epoch(stateData.epoch()); + if (context.adapter().delayIfNodePresent(stateData, -1)) { + return new MasterState(stateData); } else { - return new WorkerState(metaData); + return new WorkerState(stateData); } } @@ -267,7 +284,7 @@ public void epoch(Integer epoch) { } @Override - public MetaDataAdapter adapter() { + public RoleStataDataAdapter adapter() { return this.machine.adapter(); } @@ -287,7 +304,7 @@ public void reset() { } } - protected MetaDataAdapter adapter() { - return this.metaDataAdapter; + protected RoleStataDataAdapter adapter() { + return this.roleStataDataAdapter; } } diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleStataDataAdapter.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleStataDataAdapter.java new file mode 100644 index 0000000000..eabd17c444 --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleStataDataAdapter.java @@ -0,0 +1,31 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.election; + +import java.util.Optional; + +public interface RoleStataDataAdapter { + + boolean delayIfNodePresent(RoleStateData metaData, long delaySecond); + + Optional queryWithDelay(long delaySecond); + + Optional query(); +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleStateData.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleStateData.java new file mode 100644 index 0000000000..db728d00c6 --- /dev/null +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/RoleStateData.java @@ -0,0 +1,91 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +package com.baidu.hugegraph.election; + +import java.util.Objects; + +public class RoleStateData { + + private String node; + private long count; + private int epoch; + + public RoleStateData(String node, int epoch) { + this(node, epoch, 1); + } + + public RoleStateData(String node, int epoch, long count) { + this.node = node; + this.epoch = epoch; + this.count = count; + } + + public void increaseCount() { + this.count++; + } + + public boolean isMaster(String node) { + return Objects.equals(this.node, node); + } + + public int epoch() { + return this.epoch; + } + + public long count() { + return this.count; + } + + public void count(long count) { + this.count = count; + } + + public String node() { + return this.node; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof RoleStateData)) { + return false; + } + RoleStateData metaData = (RoleStateData) o; + return count == metaData.count && + epoch == metaData.epoch && + Objects.equals(node, metaData.node); + } + + @Override + public int hashCode() { + return Objects.hash(node, count, epoch); + } + + @Override + public String toString() { + return "RoleStateData{" + + "node='" + node + '\'' + + ", count=" + count + + ", epoch=" + epoch + + '}'; + } +} diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/StateMachineCallback.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/StateMachineCallback.java index b765c455c9..9b6b932a87 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/StateMachineCallback.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/StateMachineCallback.java @@ -1,3 +1,22 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + package com.baidu.hugegraph.election; public interface StateMachineCallback { diff --git a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/StateMachineContext.java b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/StateMachineContext.java index 74b37f337d..69251cba6f 100644 --- a/hugegraph-core/src/main/java/com/baidu/hugegraph/election/StateMachineContext.java +++ b/hugegraph-core/src/main/java/com/baidu/hugegraph/election/StateMachineContext.java @@ -1,3 +1,22 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + package com.baidu.hugegraph.election; public interface StateMachineContext { @@ -12,7 +31,7 @@ public interface StateMachineContext { Config config(); - MetaDataAdapter adapter(); + RoleStataDataAdapter adapter(); void reset(); } diff --git a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/RoleElectionStateMachineTest.java b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/RoleElectionStateMachineTest.java index 177aeb9d0e..f3214f569b 100644 --- a/hugegraph-test/src/main/java/com/baidu/hugegraph/core/RoleElectionStateMachineTest.java +++ b/hugegraph-test/src/main/java/com/baidu/hugegraph/core/RoleElectionStateMachineTest.java @@ -1,3 +1,22 @@ +/* + * Copyright 2017 HugeGraph Authors + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with this + * work for additional information regarding copyright ownership. The ASF + * licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + package com.baidu.hugegraph.core; import java.util.ArrayList; @@ -17,8 +36,8 @@ import org.junit.Test; import com.baidu.hugegraph.election.Config; -import com.baidu.hugegraph.election.MetaData; -import com.baidu.hugegraph.election.MetaDataAdapter; +import com.baidu.hugegraph.election.RoleStateData; +import com.baidu.hugegraph.election.RoleStataDataAdapter; import com.baidu.hugegraph.election.RoleElectionStateMachine; import com.baidu.hugegraph.election.RoleElectionStateMachineImpl; import com.baidu.hugegraph.election.StateMachineCallback; @@ -29,6 +48,7 @@ public class RoleElectionStateMachineTest { public static class LogEntry { Integer epoch; + String node; Role role; @@ -175,28 +195,31 @@ public void error(StateMachineContext context, Throwable e) { } }; - final List metaDataLogs = Collections.synchronizedList(new ArrayList<>(100)); - final MetaDataAdapter adapter = new MetaDataAdapter() { + final List metaDataLogs = Collections.synchronizedList(new ArrayList<>(100)); + final RoleStataDataAdapter adapter = new RoleStataDataAdapter() { + volatile int epoch = 0; - Map data = new ConcurrentHashMap<>(); - MetaData copy(MetaData metaData) { - if (metaData == null) { + final Map data = new ConcurrentHashMap<>(); + + RoleStateData copy(RoleStateData stateData) { + if (stateData == null) { return null; } - return new MetaData(metaData.node(), metaData.epoch(), metaData.count()); + return new RoleStateData(stateData.node(), stateData.epoch(), stateData.count()); } + @Override - public boolean postDelyIfPresent(MetaData metaData, long delySecond) { - if (delySecond > 0) { - LockSupport.parkNanos(delySecond * 1_000_000_000); + public boolean delayIfNodePresent(RoleStateData stateData, long delaySecond) { + if (delaySecond > 0) { + LockSupport.parkNanos(delaySecond * 1_000_000_000); } - if (metaData.epoch() < this.epoch) { + if (stateData.epoch() < this.epoch) { return false; } - MetaData copy = this.copy(metaData); - MetaData newData = data.compute(copy.epoch(), (key, value) -> { + RoleStateData copy = this.copy(stateData); + RoleStateData newData = data.compute(copy.epoch(), (key, value) -> { if (copy.epoch() > this.epoch) { this.epoch = copy.epoch(); Assert.assertNull(value); @@ -223,13 +246,13 @@ public boolean postDelyIfPresent(MetaData metaData, long delySecond) { } @Override - public Optional queryDelay(long delySecond) { - LockSupport.parkNanos(delySecond * 1_000_000_000); + public Optional queryWithDelay(long delaySecond) { + LockSupport.parkNanos(delaySecond * 1_000_000_000); return Optional.ofNullable(this.copy(this.data.get(this.epoch))); } @Override - public Optional query() { + public Optional query() { return Optional.ofNullable(this.copy(this.data.get(this.epoch))); } };