-
Notifications
You must be signed in to change notification settings - Fork 97
Passivation configured in language supports via the discovery protocol #486
Passivation configured in language supports via the discovery protocol #486
Conversation
# Conflicts: # proxy/core/src/main/resources/in-memory.conf # proxy/core/src/main/scala/io/cloudstate/proxy/EntityDiscoveryManager.scala # proxy/jdbc/src/main/resources/jdbc-common.conf
@pvlugter what do you think about the option? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Guy thinks that this option should be passed via registryXXXXEntity methods and not in the entity's annotation. I think this pollutes the entity a little.
* use default from configuration file. Any positive value means the entity is passivated after | ||
* the idle time. | ||
*/ | ||
int passivationTimeout() default 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hello Guy I didn't like this option for me it should be done at the Entity registration stage and not at the entity itself.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi Adriano, it is also fine for me and it is easier. Why do you like the option over the registration?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great! Thanks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why do you like this option?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would 0 not be a valid value? And therefore passivation disabled at all?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and it only sends a timeout if it's been configured in the user function, rather than relying on negative numbers. And the protocol could have a duration message, with time units, to make things complete.
I agree to change the protocol now and a soon as possible for such changes. I also agree on not depending on magic values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think I'd like to have options for expression the following things - perhaps not immediately, but we should choose a mechanism and protocol that allows us to add support for them in future if needed:
- A specific passivation timeout, with at least millisecond resolution.
- Default - note that I think it's fine for the default to come from the support library, I don't see any reason why the proxy needs to be in control of the default.
- No passivation timeout - entities should never passivate unless rebalanced.
- Immediate passivation, this effectively means the state is reloaded for each command.
- Some way to indicate the proxy should apply smarter, more dynamic passivation strategies, for example strategies that respond to resource constraints, or perhaps auto-tune themselves based on cardinality and/or hot spot metrics.
So, basically, I think it's worth now choosing a strategy in the APIs and protocol that will allow us to add some of the features above without breaking the protocol or APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea to future-proof the protocol and APIs now for other passivation options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Really good idea for passivation options.
More generally we should have a strategy for adding other future options (not only passivation) without breaking the protocol or the APIs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After some more discussion:
- passivation timeout in protocol can just be milliseconds, we don't expect more fine-grained than that
- language supports can use duration APIs or similar as appropriate, convert to milliseconds
- protocol should support expanding to other passivation strategies, where initially it could just be
timeout
, ideally we can addnever
orimmediate
or other strategies in a protocol-compatible way - protocol should support strategies explicitly, such as
timeout
,never
orimmediate
, and not use magic values
…entity options to pass the configured at registration time
The discovery process, the proxy and the API have been extended to support passivation strategy and also that new passivation strategy (
For the java support it will be like at the end: // passivation stratgey timeout with default passivation timeout set which is sent with entity spec to proxy
@EventSourcedEntity(persistenceId = "something")
// no extra options specified, passivation stratgey timeout with default timeout sent with entity spec to proxy
.registerEventSourcedEntity(
SomeEntity.class,
SomeProtocol.getDescriptor().findServiceByName("SomeService"),
SomeProtocol.getDescriptor())
// options specified with passivation stratgey timeout, which will be sent with entity spec to proxy
.registerEventSourcedEntity(
SomeEntity.class,
SomeProtocol.getDescriptor().findServiceByName("SomeService"),
EventSourcedEntityOptions.defaults().withPassivationStrategy(PassivationStrategy.timeout(Duration.ofSeconds(10)))
SomeProtocol.getDescriptor()) Only the java support is implemented and all others language supports (Nodejs, GO, Kotlin, Python, Spring and so on) should be extended before this can be merged. |
Thanks @ralphlaude :) For Go for sure I can help. |
@marcellanz thanks for Go. |
Hi @ralphlaude , thanks for another one! |
@sleipnir I think, it should be possible or better said desirable for language supports to evolve before the core project releases. For non-JVM supports it is already manageable with tck- and proxy images available from master. For JVM support perhaps snapshot releases help? But as you said, could be discussed elsewhere. |
Yes! But they are also often not available. |
It's easy to publish a versioned snapshot for java support. Just ask if you need one :) |
Since it's an additional field, the protocol can be compatible with older versions. In the proxy, instead of throwing exceptions if the language support doesn't define a passivation strategy, we can use the proxy-side default. I think it will be better to have this compatible and use the proxy default, rather than require all language supports to be updated straight away. There's also an older issue on configurable entity passivation (#111) which describes having the passivation strategy defined in the Kubernetes CRD or ConfigMap and injected by the operator — which would allow the proxy-side default to be configured, if the language support doesn't define it. |
The proxy-default for passivation strategy will be introduced again to allow the compatibility so we can move forward. I think it would better in the middle term to have a central place where to configure things like passivation strategy. Now we have two places where passivation strategy is configured. I think the better place for that is the language support. |
…e default passivation strategy timeout with those configured in the language support
Everything is done here. I am not sure if we want to extends the nodejs support here or do it in another issue. If yes, I will create issues for nodejs support and another language support (GO, Spring, Kotlin, Python and others). |
@ralphlaude I think for changes on the protocol one implementation for a "main" user support language should be enough. With "main" this might be JS or Java I think. As the protocol changed more often lately, it reveals how we might work with such changes in general. With changes worked on concurrently, having the proxy and TCK in the right state for development leads to a bit of coordination. This said, I think support languages should aim to get protocol updates by themselves. If the protocol changes by a PR like this one, the changing PR a) should provide a TCK test or if not applicable, b) a comment in the spec about semantics changed in the protocol. The TCK Verification here https://observablehq.com/@marcellanz/cloudstate-tck-verification displays the current situation also in an automatic way, with pending TCK tests visible. |
@ralphlaude I agree with @marcellanz but I add that the comment on the semantics desired by the protocol must be mandatory in PR. This avoids that developers have to have a long journey of understanding evaluating codes and contracts where a comment would be enough to make the intention clear. |
@marcellanz the proposal is fine for me. It would be nice to have support for nodejs. I will comment the spec about the new semantic. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good. Added a few review comments — would be good to not load the config in the Timeout static object in particular, but have the default come from the top-level config.
java-support/src/main/scala/io/cloudstate/javasupport/impl/PassivationStrategies.scala
Outdated
Show resolved
Hide resolved
proxy/core/src/main/scala/io/cloudstate/proxy/crdt/CrdtSupportFactory.scala
Outdated
Show resolved
Hide resolved
proxy/core/src/main/scala/io/cloudstate/proxy/eventsourced/EventSourcedSupportFactory.scala
Outdated
Show resolved
Hide resolved
Yes, would be good to add passivation timeouts for node support. Node support is behind the Java support in a few areas now: applying events immediately (and any failure handling for this) #375, support for value entities, new TCK implementation, and this. Doesn't need to be added to this PR, let's create an issue to track. |
Could be useful to have passivation timeouts as part of the TCK for testing. |
… creating default time out passivation strategy. fixed typos and string interpolation.
@pvlugter Could you please be more specific? |
val conf = ConfigFactory.load() | ||
conf.getConfig("cloudstate.system").withFallback(conf) | ||
}), services.asScala.toMap) | ||
this(ActorSystem("StatefulService", CloudStateConfigHolder.defaultConfiguration()), services.asScala.toMap) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the other constructor, that takes a config explicitly, that should be supported. The config gets passed to the actor system. It should also be the config that gets passed through to other places (could be retrieved from the actor system). Might be more obvious if there's a test that sets the passivation timeout in config?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pvlugter I hope my solution does the job and I did not find a better way.
Since passivation strategy is part of the protocol, it would be useful to test it in the TCK. So testing that language supports can configure this, and ideally also testing that the proxy applies the timeout and passivates the entity. For the TCK, it would be fine to have an additional entity defined which is just for testing this, since the passivation timeout is on entity discovery. |
…or passivation timeout
# Conflicts: # java-support/tck/src/main/java/io/cloudstate/javasupport/tck/JavaSupportTck.java # proxy/core/src/main/scala/io/cloudstate/proxy/UserFunctionTypeSupport.scala # proxy/core/src/main/scala/io/cloudstate/proxy/eventsourced/EventSourcedSupportFactory.scala # tck/src/main/scala/io/cloudstate/tck/CloudStateTCK.scala
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, I can always follow up with something that doesn't use a global static config
…ement the passivation strategy
@pvlugter ping! you can follow up. |
I'll just close and reopen this PR to see if we have Travis CI working again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍🏼 Good to see the global config part updated.
I'll merge this now, and include in the TCK reorganisation.
Resolves #298
Passivation timeouts configured in language supports via the discovery protocol. The first step is the java-support and then node-support.
In the java-support all entity annotations are extended
@XXXEntity (passivationTimeout = 10)
, the service classio.cloudstate.javasupport.Service
is also extented withpassivationTimeout
and the grpc entity in the entity.proto.