JeetKunDoug commented on code in PR #160:
URL: https://github.com/apache/cassandra-sidecar/pull/160#discussion_r1883999215


##########
server/src/main/java/org/apache/cassandra/sidecar/db/SidecarLeaseDatabaseAccessor.java:
##########
@@ -0,0 +1,89 @@
+/*
+ * 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.cassandra.sidecar.db;
+
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.ResultSet;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.apache.cassandra.sidecar.common.server.CQLSessionProvider;
+import org.apache.cassandra.sidecar.db.schema.SidecarLeaseSchema;
+import org.jetbrains.annotations.VisibleForTesting;
+
+/**
+ * Encapsulates database access operations for the Sidecar Lease election 
process
+ */
+@Singleton
+public class SidecarLeaseDatabaseAccessor extends 
DatabaseAccessor<SidecarLeaseSchema>
+{
+    @Inject
+    @VisibleForTesting
+    public SidecarLeaseDatabaseAccessor(SidecarLeaseSchema tableSchema, 
CQLSessionProvider sessionProvider)
+    {
+        super(tableSchema, sessionProvider);
+    }
+
+    /**
+     * Attempts to obtain the lease, returning the result of the claim
+     *
+     * @param owner the owner performing the claim
+     * @return the results of performing the lease claim
+     */
+    public LeaseClaimResult claimLease(String owner)
+    {
+        BoundStatement statement = 
tableSchema.claimLeaseStatement().bind(owner);
+        ResultSet resultSet = execute(statement);
+        return LeaseClaimResult.from(resultSet, owner);
+    }
+
+    /**
+     * Attempts to extend the existing lease, returning the result of the 
attempt
+     *
+     * @param owner the owner performing the claim
+     * @return the results of performing the lease extension
+     */
+    public LeaseClaimResult extendLease(String owner)
+    {
+        BoundStatement statement = 
tableSchema.extendLeaseStatement().bind(owner, owner);
+        ResultSet resultSet = execute(statement);
+        return LeaseClaimResult.from(resultSet, owner);
+    }
+
+    /**
+     * Captures the results of claiming lease for a given Sidecar owner
+     */
+    public static class LeaseClaimResult
+    {
+        public final boolean leaseAcquired;
+        public final String existingOwner;

Review Comment:
   do we need `existing` here? either just `owner` or maybe `currentOwner` as 
I'm not sure what exactly `existingOwner` means - is it _previous_ or _current_?



##########
server/src/main/java/org/apache/cassandra/sidecar/db/SidecarLeaseDatabaseAccessor.java:
##########
@@ -0,0 +1,89 @@
+/*
+ * 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.cassandra.sidecar.db;
+
+import com.datastax.driver.core.BoundStatement;
+import com.datastax.driver.core.ResultSet;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.apache.cassandra.sidecar.common.server.CQLSessionProvider;
+import org.apache.cassandra.sidecar.db.schema.SidecarLeaseSchema;
+import org.jetbrains.annotations.VisibleForTesting;
+
+/**
+ * Encapsulates database access operations for the Sidecar Lease election 
process
+ */
+@Singleton
+public class SidecarLeaseDatabaseAccessor extends 
DatabaseAccessor<SidecarLeaseSchema>
+{
+    @Inject
+    @VisibleForTesting
+    public SidecarLeaseDatabaseAccessor(SidecarLeaseSchema tableSchema, 
CQLSessionProvider sessionProvider)
+    {
+        super(tableSchema, sessionProvider);
+    }
+
+    /**
+     * Attempts to obtain the lease, returning the result of the claim
+     *
+     * @param owner the owner performing the claim
+     * @return the results of performing the lease claim
+     */
+    public LeaseClaimResult claimLease(String owner)

Review Comment:
   Most of the usages of `String owner` are really the hostId of the host 
attempting to _claim_ or _extend_ the lease, not the _owner_ of the lease - can 
we just use `hostId` in these instances, and reserve `owner` for cases where 
the host in question _is the owner_? See the suggestion in 
`BestEffortSingleInstanceExecutor` where I did this as well. I think the 
LeaseClaimResult usage of `owner` makes perfect sense, as an example of where 
owner makes sense vs. hostId.



##########
server/src/main/java/org/apache/cassandra/sidecar/db/schema/SidecarLeaseSchema.java:
##########
@@ -0,0 +1,113 @@
+/*
+ * 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.cassandra.sidecar.db.schema;
+
+import java.util.concurrent.TimeUnit;
+
+import com.datastax.driver.core.PreparedStatement;
+import com.datastax.driver.core.Session;
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+import org.apache.cassandra.sidecar.config.SchemaKeyspaceConfiguration;
+import org.apache.cassandra.sidecar.config.SidecarConfiguration;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.VisibleForTesting;
+
+/**
+ * Table schema definition and operations for the {@code Sidecar lease}
+ */
+@Singleton
+public class SidecarLeaseSchema extends TableSchema
+{
+    private static final String TABLE_NAME = "sidecar_lease_v1";
+
+    private final SchemaKeyspaceConfiguration keyspaceConfig;
+
+    // prepared statements
+    private PreparedStatement claimLease;
+    private PreparedStatement extendLease;
+
+    @Inject
+    public SidecarLeaseSchema(SidecarConfiguration configuration)
+    {
+        
this(configuration.serviceConfiguration().schemaKeyspaceConfiguration());
+    }
+
+    public SidecarLeaseSchema(SchemaKeyspaceConfiguration keyspaceConfig)
+    {
+        this.keyspaceConfig = keyspaceConfig;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String tableName()
+    {
+        return TABLE_NAME;
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String keyspaceName()
+    {
+        return keyspaceConfig.keyspace();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    @VisibleForTesting
+    public void prepareStatements(@NotNull Session session)
+    {
+        claimLease = prepare(claimLease, session,
+                             String.format("INSERT INTO %s.%s (name,owner) 
VALUES ('single_sidecar_instance_executor',?) IF NOT EXISTS",
+                                           keyspaceName(), tableName()));
+        extendLease = prepare(extendLease, session,
+                              String.format("UPDATE %s.%s SET owner = ? WHERE 
name = 'single_sidecar_instance_executor' IF owner = ?",
+                                            keyspaceName(), tableName()));
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    @VisibleForTesting
+    public String createSchemaStatement()
+    {
+        return String.format("CREATE TABLE IF NOT EXISTS %s.%s ("
+                             + "name text PRIMARY KEY,"
+                             + "owner text) "
+                             + "WITH default_time_to_live = %d",
+                             keyspaceName(), tableName(), 
TimeUnit.MINUTES.toSeconds(10));

Review Comment:
   NIT: Make the TTL configurable and write the rows using `USING TTL ?` so it 
can be updated easily rather than depending on the default in the table?



##########
server/src/main/java/org/apache/cassandra/sidecar/db/schema/SidecarInternalKeyspace.java:
##########
@@ -33,20 +33,19 @@
  * {@link org.apache.cassandra.sidecar.db.RestoreJob} table and {@link 
org.apache.cassandra.sidecar.db.RestoreSlice}
  * table
  */
-@Singleton
 public class SidecarInternalKeyspace extends AbstractSchema
 {
     private final SchemaKeyspaceConfiguration keyspaceConfig;
     private final boolean isEnabled;
-    private final Set<TableSchema> tableSchemas = new HashSet<>();
+    private final Set<TableSchema> tableSchemas = 
ConcurrentHashMap.newKeySet();

Review Comment:
   Was this done just to get rid of the `synchronized` on registerTableSchema 
for stylistic reasons (as I can't imaging it was a significant performance 
issue), or was there a bug this fixed?
   
   Assuming we really need to make this change, I wonder if we want to be 
specific about the type of tableSchemas to show it really needs to be 
concurrent:
   ```suggestion
       private final ConcurrentHashMap.KeySetView<TableSchema, Boolean> 
tableSchemas = ConcurrentHashMap.newKeySet();
   ```
   
   It's a bit ugly just because of the type `newKeyset` returns, but it makes 
it a bit clearer that this needs to be a concurrent set (now, why the Java 
implementers didn't just give us a ConcurrentSet to make this clear, no idea). 



##########
server/src/main/java/org/apache/cassandra/sidecar/db/schema/SidecarSchema.java:
##########
@@ -181,4 +186,23 @@ protected void reportSidecarSchemaInitialized()
     {
         vertx.eventBus().publish(ON_SIDECAR_SCHEMA_INITIALIZED.address(), 
"SidecarSchema initialized");
     }
+
+    /**
+     * Returns true when the schema should be created by this Sidecar 
instance. This currently
+     * depends on whether the election of single instance executor process is 
available, and
+     * the schemas are of type {@link InitializeOnSingleInstanceExecutor}, and 
the local Sidecar
+     * is a single instance executor. For all other types of schemas or if the 
election of leader
+     * process is unavailable we initialize the schemas.
+     *
+     * @param schema the schema to test
+     * @return {@code true} if the schema should be created by this Sidecar 
instance, {@code false} otherwise
+     */
+    protected boolean shouldCreateSchema(@Nullable AbstractSchema schema)
+    {
+        if (singleInstanceExecutor != null && schema instanceof 
InitializeOnSingleInstanceExecutor)
+        {
+            return 
singleInstanceExecutor.isLocalSidecarSingleInstanceExecutor();
+        }
+        return true;
+    }

Review Comment:
   I'm not sure if `singleInstanceExecutor` can actually be null (it doesn't 
look that way)... could we drop the null check here? If so, this method 
simplifies a bit:
   ```suggestion
       protected boolean shouldCreateSchema(@Nullable AbstractSchema schema)
       {
           return singleInstanceExecutor.isLocalSidecarSingleInstanceExecutor() 
|| 
                  !(schema instanceof InitializeOnSingleInstanceExecutor);
       }
   ```



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to