frankgh commented on code in PR #200:
URL: https://github.com/apache/cassandra-sidecar/pull/200#discussion_r1966570408
##########
CONTRIBUTING.md:
##########
@@ -128,57 +159,94 @@ The `service` worker pool has the name
`sidecar-worker-pool`.
The `internal` worker pool has the name `sidecar-internal-worker-pool`.
-### <a href="timers"></a>One-shot Timers and Periodic Timers
+### <a name="timers"></a>One-shot Timers and Periodic Timers
Use vertx APIs to set one-shot timers and periodic timers. If you need to
execute a one-time operation in the future,
or if you need to run periodic operations within vertx, an API is available.
These timers utilize vertx provisioned
-threads that are managed internal by vertx. For example
+threads that are managed internal by vertx. For example, the below code
snippet runs `action()` after `delayMillis`.
```java
-logger.debug("Retrying streaming after {} millis", millis);
-executorPools.service().setTimer(millis, t -> acquireAndSend(context,
filename, fileLength, range, startTime));
+executorPools.service().setTimer(delayMillis, timerId -> action());
```
-### <a href="guice"></a>Dependency Injection
+Similarly, a simple periodic task can be schedule with the following code. The
`action()` is scheduled to run after
Review Comment:
```suggestion
Similarly, a simple periodic task can be scheduled with the following code.
The `action()` is scheduled to run after
```
##########
CONTRIBUTING.md:
##########
@@ -128,57 +159,94 @@ The `service` worker pool has the name
`sidecar-worker-pool`.
The `internal` worker pool has the name `sidecar-internal-worker-pool`.
-### <a href="timers"></a>One-shot Timers and Periodic Timers
+### <a name="timers"></a>One-shot Timers and Periodic Timers
Use vertx APIs to set one-shot timers and periodic timers. If you need to
execute a one-time operation in the future,
or if you need to run periodic operations within vertx, an API is available.
These timers utilize vertx provisioned
-threads that are managed internal by vertx. For example
+threads that are managed internal by vertx. For example, the below code
snippet runs `action()` after `delayMillis`.
```java
-logger.debug("Retrying streaming after {} millis", millis);
-executorPools.service().setTimer(millis, t -> acquireAndSend(context,
filename, fileLength, range, startTime));
+executorPools.service().setTimer(delayMillis, timerId -> action());
```
-### <a href="guice"></a>Dependency Injection
+Similarly, a simple periodic task can be schedule with the following code. The
`action()` is scheduled to run after
+the `initialDelayMillis` and repeat every `delayMillis`.
-The Apache Cassandra Sidecar project uses Guice for handling the object
interdependency. When a class encapsulates
-some functionality that is then used by a different class in the system, we
use Guice for dependency injection.
+```java
+executorPools.internal().setPeriodic(initialDelayMillis, delayMillis, timerId
-> action());
+```
+Note that such periodic task is triggered whenever the scheduled time has
arrived, consider the equivalent
+`ScheduledExecutorService#scheduleAtFixedRate`. It is possible to have
concurrent runs, depending on the delay parameters.
+It might not be the desired scheduling behavior for the use case. If serial
execution sequence is wanted, check out the
+scheduling mechanism described in [Advanced periodic task
scheduling](#advanced-periodic-scheduling)
-When a different implementation can be provided in the future, prefer using an
interface and a default implementation
-that can be later switched transparently without affecting the classes that
depend on it.
+#### <a name="advanced-periodic-scheduling">Advanced periodic task scheduling
-Prefer creating concrete classes over utility methods. The concrete classes
can be managed as a
-[Singleton](https://en.wikipedia.org/wiki/Singleton_pattern) if they do not
have external dependencies that might
-change their behavior based on the configuration.
+`PeriodicTaskExecutor` provides the scheduling behavior that is similar to the
hybrid of `ScheduledExecutorService#scheduleAtFixedRate`
+and `ScheduledExecutorService#scheduleAtFixedDelay`. The unit of execution is
`PeriodicTask`.
-Here's an example of a class being managed by Guice.
+A `PeriodicTask` is guaranteed to be executed in serial by
`PeriodicTaskExecutor`, as if such task is executed from
+a single thread. Memory consistency is ensured, i.e. the effect of write from
the last run is visible to the current run.
+The interval between the consecutive runs is adjusted based on the duration
taken by the last run. This way, its behavior
Review Comment:
I think we should not here that the duration is determined by the
PeriodicTask, if the future returns immediately, but there are background tasks
scheduled within the PeriodicTask, the duration of the actual task is not known
to the scheduler
##########
CHANGES.txt:
##########
@@ -1,5 +1,6 @@
0.1.0
-----
+ * Guice modularization (CASSSIDECAR-208)
Review Comment:
this feature should go under 0.2.0 instead
##########
server/src/main/java/org/apache/cassandra/sidecar/datahub/SchemaReportingTask.java:
##########
@@ -61,6 +63,13 @@ public SchemaReportingTask(@NotNull SidecarConfiguration
configuration,
this.reporter = reporter;
}
+ @Override
+ public void deploy(Vertx vertx, PeriodicTaskExecutor executor)
+ {
+ // TODO: react on ON_CASSANDRA_CQL_READY instead? When any CQL
connection is ready, cluster metadata should be available from session
Review Comment:
this actually sounds like a bug. If your Sidecar instance manages multiple
Cassandra instances, and your sidecar instance happens to be the cluster
leaseholder, this task will never schedule and you will never perform the
schema reporting unless another Sidecar instance takes over the cluster
leadership.
##########
server/src/main/java/org/apache/cassandra/sidecar/restore/RestoreJobManagerGroup.java:
##########
@@ -57,18 +56,12 @@ public class RestoreJobManagerGroup
public RestoreJobManagerGroup(SidecarConfiguration configuration,
InstancesMetadata instancesMetadata,
ExecutorPools executorPools,
- PeriodicTaskExecutor periodicTaskExecutor,
- RestoreProcessor restoreProcessor,
- RestoreJobDiscoverer jobDiscoverer,
- RingTopologyRefresher ringTopologyRefresher)
+ RestoreProcessor restoreProcessor)
{
this.restoreJobConfig = configuration.restoreJobConfiguration();
this.restoreProcessor = restoreProcessor;
this.executorPools = executorPools;
initializeManagers(instancesMetadata);
- periodicTaskExecutor.schedule(jobDiscoverer);
Review Comment:
nice 👍
##########
server/src/main/java/org/apache/cassandra/sidecar/acl/authentication/ReloadingJwtAuthenticationHandler.java:
##########
@@ -174,6 +173,7 @@ public void execute(Promise<Void> promise)
if (!jwtParameters.enabled())
{
delegateHandler.set(null);
+ promise.complete();
Review Comment:
good catch
##########
server/src/main/java/org/apache/cassandra/sidecar/modules/guice-best-practice.md:
##########
@@ -0,0 +1,117 @@
+<!--
+#
+# 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.
+#
+-->
+
+# Guice Best Practices in Sidecar
+
+First of all, refer to [Guice
Wiki](https://github.com/google/guice/wiki/BestPractices) for the best
practices in general.
+
+There are certain project-specific best practices we advocate for Apache
Sidecar. This article capture those items in the below.
Review Comment:
```suggestion
There are certain project-specific best practices we advocate for Apache
Cassandra Sidecar. This article capture those items in the below.
```
##########
CONTRIBUTING.md:
##########
@@ -128,57 +159,94 @@ The `service` worker pool has the name
`sidecar-worker-pool`.
The `internal` worker pool has the name `sidecar-internal-worker-pool`.
-### <a href="timers"></a>One-shot Timers and Periodic Timers
+### <a name="timers"></a>One-shot Timers and Periodic Timers
Use vertx APIs to set one-shot timers and periodic timers. If you need to
execute a one-time operation in the future,
or if you need to run periodic operations within vertx, an API is available.
These timers utilize vertx provisioned
-threads that are managed internal by vertx. For example
+threads that are managed internal by vertx. For example, the below code
snippet runs `action()` after `delayMillis`.
```java
-logger.debug("Retrying streaming after {} millis", millis);
-executorPools.service().setTimer(millis, t -> acquireAndSend(context,
filename, fileLength, range, startTime));
+executorPools.service().setTimer(delayMillis, timerId -> action());
```
-### <a href="guice"></a>Dependency Injection
+Similarly, a simple periodic task can be schedule with the following code. The
`action()` is scheduled to run after
+the `initialDelayMillis` and repeat every `delayMillis`.
-The Apache Cassandra Sidecar project uses Guice for handling the object
interdependency. When a class encapsulates
-some functionality that is then used by a different class in the system, we
use Guice for dependency injection.
+```java
+executorPools.internal().setPeriodic(initialDelayMillis, delayMillis, timerId
-> action());
+```
+Note that such periodic task is triggered whenever the scheduled time has
arrived, consider the equivalent
+`ScheduledExecutorService#scheduleAtFixedRate`. It is possible to have
concurrent runs, depending on the delay parameters.
+It might not be the desired scheduling behavior for the use case. If serial
execution sequence is wanted, check out the
+scheduling mechanism described in [Advanced periodic task
scheduling](#advanced-periodic-scheduling)
-When a different implementation can be provided in the future, prefer using an
interface and a default implementation
-that can be later switched transparently without affecting the classes that
depend on it.
+#### <a name="advanced-periodic-scheduling">Advanced periodic task scheduling
Review Comment:
NIT: uppercase first letter for the title
```suggestion
#### <a name="advanced-periodic-scheduling">Advanced Periodic Task Scheduling
```
##########
server/src/main/java/org/apache/cassandra/sidecar/cluster/instance/InstanceMetadataImpl.java:
##########
@@ -423,8 +423,8 @@ public InstanceMetadataImpl build()
if (storageDir == null)
{
- Objects.requireNonNull(dataDirs, "dataDirs are required when
storageDir is not configured");
- Preconditions.checkArgument(!dataDirs.isEmpty(), "dataDirs are
required when storageDir is not configured");
+ Preconditions.checkArgument(dataDirs != null &&
!dataDirs.isEmpty(),
Review Comment:
I think it's better to have an NPE for null input and
IllegalArgumentException for empty. Also this change is unrelated to this PR,
can you please revert?
##########
server/src/main/java/org/apache/cassandra/sidecar/modules/guice-best-practice.md:
##########
@@ -0,0 +1,117 @@
+<!--
+#
+# 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.
+#
+-->
+
+# Guice Best Practices in Sidecar
+
+First of all, refer to [Guice
Wiki](https://github.com/google/guice/wiki/BestPractices) for the best
practices in general.
+
+There are certain project-specific best practices we advocate for Apache
Sidecar. This article capture those items in the below.
+
+## Multi-bindings for Plugin Extension
+
+[Multi-bindings](https://github.com/google/guice/wiki/Multibindings) is a
Guice feature to support the plugin-type architecture,
+where multiple modules contribute components to plug into the system.
+
+The applications of multi-bindings in Sidecar are, for example,
+1. Routes definition
+2. Periodic tasks deployment
+3. Sidecar internal schemas creation
Review Comment:
I don't think this is scoped to sidecar internal schemas only, for example
system_auth is also managed by multi-bindings, as a read-only table
##########
server/src/test/java/org/apache/cassandra/sidecar/routes/sstableuploads/BaseUploadsHandlerTest.java:
##########
Review Comment:
all the tests under the `org.apache.cassandra.sidecar.routes` package should
move to the `org.apache.cassandra.sidecar.handlers` package
--
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]