Skip to content
This repository has been archived by the owner on Mar 16, 2022. It is now read-only.

Passivation configured in language supports via the discovery protocol #486

Merged
merged 17 commits into from
Dec 17, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 94 additions & 6 deletions java-support/src/main/java/io/cloudstate/javasupport/CloudState.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@
import akka.stream.Materializer;
import com.typesafe.config.Config;
import com.google.protobuf.Descriptors;
import io.cloudstate.javasupport.crdt.CrdtEntityOptions;
import io.cloudstate.javasupport.entity.EntityOptions;
import io.cloudstate.javasupport.eventsourced.EventSourcedEntityOptions;
import io.cloudstate.javasupport.impl.entity.AnnotationBasedEntitySupport;
import io.cloudstate.javasupport.entity.Entity;
import io.cloudstate.javasupport.action.Action;
Expand All @@ -39,6 +42,7 @@
import io.cloudstate.javasupport.impl.eventsourced.EventSourcedStatefulService;

import akka.Done;

import java.util.concurrent.CompletionStage;
import java.util.HashMap;
import java.util.Map;
Expand Down Expand Up @@ -117,6 +121,29 @@ public CloudState registerEventSourcedEntity(
Descriptors.ServiceDescriptor descriptor,
Descriptors.FileDescriptor... additionalDescriptors) {

return registerEventSourcedEntity(
entityClass, descriptor, EventSourcedEntityOptions.defaults(), additionalDescriptors);
}

/**
* Register an annotated event sourced entity.
*
* <p>The entity class must be annotated with {@link
* io.cloudstate.javasupport.eventsourced.EventSourcedEntity}.
*
* @param entityClass The entity class.
* @param descriptor The descriptor for the service that this entity implements.
* @param entityOptions The entity options.
* @param additionalDescriptors Any additional descriptors that should be used to look up protobuf
* types when needed.
* @return This stateful service builder.
*/
public CloudState registerEventSourcedEntity(
Class<?> entityClass,
Descriptors.ServiceDescriptor descriptor,
EventSourcedEntityOptions entityOptions,
Descriptors.FileDescriptor... additionalDescriptors) {

EventSourcedEntity entity = entityClass.getAnnotation(EventSourcedEntity.class);
if (entity == null) {
throw new IllegalArgumentException(
Expand All @@ -141,7 +168,8 @@ public CloudState registerEventSourcedEntity(
descriptor,
anySupport,
persistenceId,
snapshotEvery);
snapshotEvery,
entityOptions);

services.put(descriptor.getFullName(), system -> service);

Expand All @@ -160,6 +188,7 @@ public CloudState registerEventSourcedEntity(
* @param snapshotEvery Specifies how snapshots of the entity state should be made: Zero means use
* default from configuration file. (Default) Any negative value means never snapshot. Any
* positive value means snapshot at-or-after that number of events.
* @param entityOptions the options for this entity.
* @param additionalDescriptors Any additional descriptors that should be used to look up protobuf
* types when needed.
* @return This stateful service builder.
Expand All @@ -169,7 +198,9 @@ public CloudState registerEventSourcedEntity(
Descriptors.ServiceDescriptor descriptor,
String persistenceId,
int snapshotEvery,
EventSourcedEntityOptions entityOptions,
Descriptors.FileDescriptor... additionalDescriptors) {

services.put(
descriptor.getFullName(),
system ->
Expand All @@ -178,7 +209,8 @@ public CloudState registerEventSourcedEntity(
descriptor,
newAnySupport(additionalDescriptors),
persistenceId,
snapshotEvery));
snapshotEvery,
entityOptions));

return this;
}
Expand All @@ -199,6 +231,28 @@ public CloudState registerCrdtEntity(
Descriptors.ServiceDescriptor descriptor,
Descriptors.FileDescriptor... additionalDescriptors) {

return registerCrdtEntity(
entityClass, descriptor, CrdtEntityOptions.defaults(), additionalDescriptors);
}

/**
* Register an annotated CRDT entity.
*
* <p>The entity class must be annotated with {@link io.cloudstate.javasupport.crdt.CrdtEntity}.
*
* @param entityClass The entity class.
* @param descriptor The descriptor for the service that this entity implements.
* @param entityOptions The options for this entity.
* @param additionalDescriptors Any additional descriptors that should be used to look up protobuf
* types when needed.
* @return This stateful service builder.
*/
public CloudState registerCrdtEntity(
Class<?> entityClass,
Descriptors.ServiceDescriptor descriptor,
CrdtEntityOptions entityOptions,
Descriptors.FileDescriptor... additionalDescriptors) {

CrdtEntity entity = entityClass.getAnnotation(CrdtEntity.class);
if (entity == null) {
throw new IllegalArgumentException(
Expand All @@ -211,7 +265,8 @@ public CloudState registerCrdtEntity(
new CrdtStatefulService(
new AnnotationBasedCrdtSupport(entityClass, anySupport, descriptor),
descriptor,
anySupport);
anySupport,
entityOptions);

services.put(descriptor.getFullName(), system -> service);

Expand All @@ -226,18 +281,22 @@ public CloudState registerCrdtEntity(
*
* @param factory The CRDT factory.
* @param descriptor The descriptor for the service that this entity implements.
* @param entityOptions The options for this entity.
* @param additionalDescriptors Any additional descriptors that should be used to look up protobuf
* types when needed.
* @return This stateful service builder.
*/
public CloudState registerCrdtEntity(
CrdtEntityFactory factory,
Descriptors.ServiceDescriptor descriptor,
CrdtEntityOptions entityOptions,
Descriptors.FileDescriptor... additionalDescriptors) {

services.put(
descriptor.getFullName(),
system ->
new CrdtStatefulService(factory, descriptor, newAnySupport(additionalDescriptors)));
new CrdtStatefulService(
factory, descriptor, newAnySupport(additionalDescriptors), entityOptions));

return this;
}
Expand Down Expand Up @@ -320,6 +379,27 @@ public CloudState registerEntity(
Descriptors.ServiceDescriptor descriptor,
Descriptors.FileDescriptor... additionalDescriptors) {

return registerEntity(entityClass, descriptor, EntityOptions.defaults(), additionalDescriptors);
}

/**
* Register an annotated value based entity.
*
* <p>The entity class must be annotated with {@link Entity}.
*
* @param entityClass The entity class.
* @param descriptor The descriptor for the service that this entity implements.
* @param entityOptions The options for this entity.
* @param additionalDescriptors Any additional descriptors that should be used to look up protobuf
* types when needed.
* @return This stateful service builder.
*/
public CloudState registerEntity(
Class<?> entityClass,
Descriptors.ServiceDescriptor descriptor,
EntityOptions entityOptions,
Descriptors.FileDescriptor... additionalDescriptors) {

Entity entity = entityClass.getAnnotation(Entity.class);
if (entity == null) {
throw new IllegalArgumentException(
Expand All @@ -339,7 +419,8 @@ public CloudState registerEntity(
new AnnotationBasedEntitySupport(entityClass, anySupport, descriptor),
descriptor,
anySupport,
persistenceId);
persistenceId,
entityOptions);

services.put(descriptor.getFullName(), system -> service);

Expand All @@ -355,6 +436,7 @@ public CloudState registerEntity(
* @param factory The value based entity factory.
* @param descriptor The descriptor for the service that this entity implements.
* @param persistenceId The persistence id for this entity.
* @param entityOptions The options for this entity.
* @param additionalDescriptors Any additional descriptors that should be used to look up protobuf
* types when needed.
* @return This stateful service builder.
Expand All @@ -363,12 +445,18 @@ public CloudState registerEntity(
EntityFactory factory,
Descriptors.ServiceDescriptor descriptor,
String persistenceId,
EntityOptions entityOptions,
Descriptors.FileDescriptor... additionalDescriptors) {

services.put(
descriptor.getFullName(),
system ->
new ValueEntityStatefulService(
factory, descriptor, newAnySupport(additionalDescriptors), persistenceId));
factory,
descriptor,
newAnySupport(additionalDescriptors),
persistenceId,
entityOptions));

return this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright 2019 Lightbend Inc.
*
* Licensed 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 io.cloudstate.javasupport;

/** Options used for configuring an entity. */
public interface EntityOptions {

/** @return the passivation strategy for an entity */
PassivationStrategy passivationStrategy();

/**
* Create an entity option with the given passivation strategy.
*
* @param strategy to be used
* @return the entity option
*/
EntityOptions withPassivationStrategy(PassivationStrategy strategy);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright 2019 Lightbend Inc.
*
* Licensed 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 io.cloudstate.javasupport;

import io.cloudstate.javasupport.impl.Timeout;

import java.time.Duration;

/** A passivation strategy. */
public interface PassivationStrategy {

/**
* Create a passivation strategy that passivates the entity after the default duration (30
* seconds) of inactivity.
*
* @return the passivation strategy
*/
static PassivationStrategy defaultTimeout() {
return new Timeout();
}

/**
* Create a passivation strategy that passivates the entity after a given duration of inactivity.
*
* @param duration of inactivity after which the passivation should occur.
* @return the passivation strategy
*/
static PassivationStrategy timeout(Duration duration) {
return new Timeout(duration);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Copyright 2019 Lightbend Inc.
*
* Licensed 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 io.cloudstate.javasupport.crdt;

import io.cloudstate.javasupport.EntityOptions;
import io.cloudstate.javasupport.PassivationStrategy;
import io.cloudstate.javasupport.impl.crdt.CrdtEntityOptionsImpl;

/** Root entity options for all CRDT. */
public interface CrdtEntityOptions extends EntityOptions {

CrdtEntityOptions withPassivationStrategy(PassivationStrategy strategy);

/**
* Create a default CRDT entity option.
*
* @return the entity option
*/
static CrdtEntityOptions defaults() {
return new CrdtEntityOptionsImpl(PassivationStrategy.defaultTimeout());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright 2019 Lightbend Inc.
*
* Licensed 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 io.cloudstate.javasupport.entity;

import io.cloudstate.javasupport.PassivationStrategy;
import io.cloudstate.javasupport.impl.entity.ValueEntityOptionsImpl;

/** Root entity options for all value based entities. */
public interface EntityOptions extends io.cloudstate.javasupport.EntityOptions {

EntityOptions withPassivationStrategy(PassivationStrategy strategy);

/**
* Create a default entity option for a value based entity.
*
* @return the entity option
*/
static EntityOptions defaults() {
return new ValueEntityOptionsImpl(PassivationStrategy.defaultTimeout());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
/**
* The name of the persistence id.
*
* <p>If not specifed, defaults to the entities unqualified classname. It's strongly recommended
* <p>If not specified, defaults to the entities unqualified classname. It's strongly recommended
* that you specify it explicitly.
*/
String persistenceId() default "";
Expand Down
Loading