You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by me...@apache.org on 2022/06/16 12:30:15 UTC
[shardingsphere] branch master updated: Refactor lock judge engine by SPI (#18394)
This is an automated email from the ASF dual-hosted git repository.
menghaoran pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git
The following commit(s) were added to refs/heads/master by this push:
new 93ec14e509d Refactor lock judge engine by SPI (#18394)
93ec14e509d is described below
commit 93ec14e509d6548df177d69869da9a32c36cde55
Author: gin <ja...@163.com>
AuthorDate: Thu Jun 16 20:30:02 2022 +0800
Refactor lock judge engine by SPI (#18394)
* Refactor lock judge engine by SPI
* Fix IT
---
...reLockJudgeEngine.java => LockJudgeEngine.java} | 36 +++++++---------
.../mode/manager/lock/LockJudgeEngineBuilder.java | 47 +++++++++++++++++++++
.../lock/ShardingSphereLockJudgeEngine.java | 48 ++++++++++++++++++----
...hardingsphere.mode.manager.lock.LockJudgeEngine | 18 ++++++++
.../lock/ShardingSphereLockJudgeEngineTest.java | 47 +++++++++++++++++----
.../communication/DatabaseCommunicationEngine.java | 9 ++--
6 files changed, 162 insertions(+), 43 deletions(-)
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngine.java b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/LockJudgeEngine.java
similarity index 50%
copy from shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngine.java
copy to shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/LockJudgeEngine.java
index bb80d07daf2..36860d77089 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngine.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/LockJudgeEngine.java
@@ -17,38 +17,30 @@
package org.apache.shardingsphere.mode.manager.lock;
-import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.lock.LockContext;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DDLStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DMLStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
+import org.apache.shardingsphere.spi.annotation.SingletonSPI;
+import org.apache.shardingsphere.spi.type.required.RequiredSPI;
/**
- * Lock judge engine for ShardingSphere.
+ * Lock judge engine.
*/
-@RequiredArgsConstructor
-public final class ShardingSphereLockJudgeEngine {
+@SingletonSPI
+public interface LockJudgeEngine extends RequiredSPI {
- private final LockContext lockContext;
+ /**
+ * Init.
+ *
+ * @param lockContext lock context
+ */
+ void init(LockContext lockContext);
/**
* Is locked.
*
* @param databaseName database name
- * @param sqlStatement sql statement
+ * @param sqlStatementContext sql statement context
* @return is locked or not
*/
- public boolean isLocked(final String databaseName, final SQLStatement sqlStatement) {
- if (sqlStatement instanceof DMLStatement) {
- if (sqlStatement instanceof SelectStatement) {
- return false;
- }
- return lockContext.isLocked(databaseName);
- }
- if (sqlStatement instanceof DDLStatement) {
- return lockContext.isLocked(databaseName);
- }
- return false;
- }
+ boolean isLocked(String databaseName, SQLStatementContext<?> sqlStatementContext);
}
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/LockJudgeEngineBuilder.java b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/LockJudgeEngineBuilder.java
new file mode 100644
index 00000000000..59e170712c6
--- /dev/null
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/LockJudgeEngineBuilder.java
@@ -0,0 +1,47 @@
+/*
+ * 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 org.apache.shardingsphere.mode.manager.lock;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.infra.lock.LockContext;
+import org.apache.shardingsphere.spi.ShardingSphereServiceLoader;
+import org.apache.shardingsphere.spi.type.required.RequiredSPIRegistry;
+
+/**
+ * Lock judge engine builder.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class LockJudgeEngineBuilder {
+
+ static {
+ ShardingSphereServiceLoader.register(LockJudgeEngine.class);
+ }
+
+ /**
+ * Build.
+ *
+ * @param lockContext lock context
+ * @return lock judge engine
+ */
+ public static LockJudgeEngine build(final LockContext lockContext) {
+ LockJudgeEngine result = RequiredSPIRegistry.getRegisteredService(LockJudgeEngine.class);
+ result.init(lockContext);
+ return result;
+ }
+}
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngine.java b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngine.java
index bb80d07daf2..598f8e4a15c 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngine.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngine.java
@@ -18,37 +18,67 @@
package org.apache.shardingsphere.mode.manager.lock;
import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.lock.LockContext;
import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DDLStatement;
import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DMLStatement;
import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
/**
* Lock judge engine for ShardingSphere.
*/
@RequiredArgsConstructor
-public final class ShardingSphereLockJudgeEngine {
+public final class ShardingSphereLockJudgeEngine implements LockJudgeEngine {
+
+ private static final Set<Class<? extends SQLStatement>> IGNORABLE_SQL_STATEMENT_CLASSES_STOP_WRITING = Collections.newSetFromMap(new ConcurrentHashMap<>());
- private final LockContext lockContext;
+ private LockContext lockContext;
+
+ @Override
+ public void init(final LockContext lockContext) {
+ this.lockContext = lockContext;
+ }
/**
* Is locked.
*
* @param databaseName database name
- * @param sqlStatement sql statement
+ * @param sqlStatementContext sql statement context
* @return is locked or not
*/
- public boolean isLocked(final String databaseName, final SQLStatement sqlStatement) {
- if (sqlStatement instanceof DMLStatement) {
- if (sqlStatement instanceof SelectStatement) {
- return false;
- }
+ @Override
+ public boolean isLocked(final String databaseName, final SQLStatementContext<?> sqlStatementContext) {
+ if (isWriteStatement(sqlStatementContext.getSqlStatement())) {
return lockContext.isLocked(databaseName);
}
+ return false;
+ }
+
+ private boolean isWriteStatement(final SQLStatement sqlStatement) {
+ Class<? extends SQLStatement> sqlStatementClass = sqlStatement.getClass();
+ if (IGNORABLE_SQL_STATEMENT_CLASSES_STOP_WRITING.contains(sqlStatementClass)) {
+ return false;
+ }
+ if (sqlStatement instanceof SelectStatement) {
+ catchIgnorable(sqlStatementClass);
+ return false;
+ }
+ if (sqlStatement instanceof DMLStatement) {
+ return true;
+ }
if (sqlStatement instanceof DDLStatement) {
- return lockContext.isLocked(databaseName);
+ return true;
}
+ catchIgnorable(sqlStatementClass);
return false;
}
+
+ private void catchIgnorable(final Class<? extends SQLStatement> sqlStatementClass) {
+ IGNORABLE_SQL_STATEMENT_CLASSES_STOP_WRITING.add(sqlStatementClass);
+ }
}
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/main/resources/META-INF/services/org.apache.shardingsphere.mode.manager.lock.LockJudgeEngine b/shardingsphere-mode/shardingsphere-mode-core/src/main/resources/META-INF/services/org.apache.shardingsphere.mode.manager.lock.LockJudgeEngine
new file mode 100644
index 00000000000..0b5e3c4c1ba
--- /dev/null
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/main/resources/META-INF/services/org.apache.shardingsphere.mode.manager.lock.LockJudgeEngine
@@ -0,0 +1,18 @@
+#
+# 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.
+#
+
+org.apache.shardingsphere.mode.manager.lock.ShardingSphereLockJudgeEngine
diff --git a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngineTest.java b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngineTest.java
index 5df07a41820..f8a3ab3e31e 100644
--- a/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngineTest.java
+++ b/shardingsphere-mode/shardingsphere-mode-core/src/test/java/org/apache/shardingsphere/mode/manager/lock/ShardingSphereLockJudgeEngineTest.java
@@ -17,6 +17,11 @@
package org.apache.shardingsphere.mode.manager.lock;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.dml.DeleteStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.dml.InsertStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
+import org.apache.shardingsphere.infra.binder.statement.dml.UpdateStatementContext;
import org.apache.shardingsphere.infra.lock.LockContext;
import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DDLStatement;
import org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DeleteStatement;
@@ -33,21 +38,47 @@ import static org.mockito.Mockito.when;
public final class ShardingSphereLockJudgeEngineTest {
- private ShardingSphereLockJudgeEngine engine;
+ private LockJudgeEngine engine;
@Before
public void setUp() {
LockContext lockContext = mock(LockContext.class);
when(lockContext.isLocked("databaseName")).thenReturn(true);
- engine = new ShardingSphereLockJudgeEngine(lockContext);
+ engine = LockJudgeEngineBuilder.build(lockContext);
}
@Test
- public void assertIsLocked() {
- assertTrue(engine.isLocked("databaseName", mock(InsertStatement.class)));
- assertTrue(engine.isLocked("databaseName", mock(UpdateStatement.class)));
- assertTrue(engine.isLocked("databaseName", mock(DeleteStatement.class)));
- assertTrue(engine.isLocked("databaseName", mock(DDLStatement.class)));
- assertFalse(engine.isLocked("databaseName", mock(SelectStatement.class)));
+ public void assertDDLIsLocked() {
+ SQLStatementContext<DDLStatement> sqlStatementContext = mock(SQLStatementContext.class);
+ when(sqlStatementContext.getSqlStatement()).thenReturn(mock(DDLStatement.class));
+ assertTrue(engine.isLocked("databaseName", sqlStatementContext));
+ }
+
+ @Test
+ public void assertInsertIsLocked() {
+ InsertStatementContext insertStatementContext = mock(InsertStatementContext.class);
+ when(insertStatementContext.getSqlStatement()).thenReturn(mock(InsertStatement.class));
+ assertTrue(engine.isLocked("databaseName", insertStatementContext));
+ }
+
+ @Test
+ public void assertUpdateIsLocked() {
+ UpdateStatementContext updateStatementContext = mock(UpdateStatementContext.class);
+ when(updateStatementContext.getSqlStatement()).thenReturn(mock(UpdateStatement.class));
+ assertTrue(engine.isLocked("databaseName", updateStatementContext));
+ }
+
+ @Test
+ public void assertDeleteIsLocked() {
+ DeleteStatementContext deleteStatementContext = mock(DeleteStatementContext.class);
+ when(deleteStatementContext.getSqlStatement()).thenReturn(mock(DeleteStatement.class));
+ assertTrue(engine.isLocked("databaseName", deleteStatementContext));
+ }
+
+ @Test
+ public void assertSelectIsLocked() {
+ SelectStatementContext selectStatementContext = mock(SelectStatementContext.class);
+ when(selectStatementContext.getSqlStatement()).thenReturn(mock(SelectStatement.class));
+ assertFalse(engine.isLocked("databaseName", selectStatementContext));
}
}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/DatabaseCommunicationEngine.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/DatabaseCommunicationEngine.java
index eff0d08e2a9..34ca5592d90 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/DatabaseCommunicationEngine.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/communication/DatabaseCommunicationEngine.java
@@ -38,7 +38,8 @@ import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.event.MetaDataRefreshedEvent;
import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
import org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule;
-import org.apache.shardingsphere.mode.manager.lock.ShardingSphereLockJudgeEngine;
+import org.apache.shardingsphere.mode.manager.lock.LockJudgeEngine;
+import org.apache.shardingsphere.mode.manager.lock.LockJudgeEngineBuilder;
import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
import org.apache.shardingsphere.proxy.backend.exception.DatabaseLockedException;
import org.apache.shardingsphere.proxy.backend.response.data.QueryResponseCell;
@@ -82,7 +83,7 @@ public abstract class DatabaseCommunicationEngine<T> {
private final BackendConnection<?> backendConnection;
- private final ShardingSphereLockJudgeEngine lockJudgeEngine;
+ private final LockJudgeEngine lockJudgeEngine;
public DatabaseCommunicationEngine(final String driverType, final ShardingSphereDatabase database, final LogicSQL logicSQL, final BackendConnection<?> backendConnection) {
this.driverType = driverType;
@@ -94,7 +95,7 @@ public abstract class DatabaseCommunicationEngine<T> {
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getOptimizerContext().getFederationMetaData().getDatabases().get(databaseName),
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getOptimizerContext().getPlannerContexts(),
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getProps());
- lockJudgeEngine = new ShardingSphereLockJudgeEngine(ProxyContext.getInstance().getContextManager().getInstanceContext().getLockContext());
+ lockJudgeEngine = LockJudgeEngineBuilder.build(ProxyContext.getInstance().getContextManager().getInstanceContext().getLockContext());
}
/**
@@ -222,7 +223,7 @@ public abstract class DatabaseCommunicationEngine<T> {
}
protected void checkLockedDatabase(final ExecutionContext executionContext) {
- if (lockJudgeEngine.isLocked(backendConnection.getConnectionSession().getDatabaseName(), executionContext.getSqlStatementContext().getSqlStatement())) {
+ if (lockJudgeEngine.isLocked(backendConnection.getConnectionSession().getDatabaseName(), executionContext.getSqlStatementContext())) {
throw new DatabaseLockedException(backendConnection.getConnectionSession().getDatabaseName());
}
}