kalix-jvm-sdk
kalix-jvm-sdk copied to clipboard
Inject KalixClient or WebClientProvider to Spring components.
Currently, I don't allow it KalixClient can only be injected in Kalix Actions and Workflows.
, but is there a technical reason behind it? I understand that injecting Kalix entities would cause a lot of confusion, but clients?
My rationale behind it: I have a subscription that launches some actions against a Kalix component via KalixClient. I would like to simulate a disturbance in my system, e.g. a timeout or sth that will slow down, or even restart the whole projection/subscription. My idea was to wrap the KalixClient with Spring bean and inject this bean into the subscription action. In a test, I would override this bean definition with a failing one, via @MockBean
or any other mechanism.
Maybe I'm solving the wrong problem, any thoughts?
We don't want it injected in entities (async callbacks over state that may have changed since etc) could perhaps be one reason. But maybe it would be possible to block just those instead (and components transitively injected into entities, maybe that is the tricky part)?
It's already not possible to inject Kalix components into other Kalix components, but also not possible to inject Kalix components in any other place. Basically, Kalix components always be at the top level.
Injecting a client in a non Kalix components is in principle not a problem, but could leave to the following situations:
(java pseudo-code ahead)
class SomeOtherComponent(WebClientProvider webClientProvider)
class MyKalixEntity(SomeOtherComponent someOtherComponent) extends EventSourcedEntity {
private WebClient client = someOtherComponent.webClientProvider.clientFor(...)
}
Now we can have a client inside an entity.
Well, if you want to hack the entity, you can do this anyway with a static method.
Transitively calling some other service through an injected component is not something I'd call a hack, rather something that we should guard against if we want Kalix to guide users to not do bad design. Or we decide that we don't care and it is their problem, if that is the direction we want to go I think we can allow injecting the client directly in entities as well but there will be concurrency issues lurking there for users if they mix entity logic with async callbacks.
I think we have to do this anyway because most of the effect builders allow us to run a forward call:
effects()
.updateState(???)
.thenForward(???)
Related issue for forward: https://github.com/lightbend/kalix-jvm-sdk/issues/673
I don't recall that I have pledged for this (#673), but that's consistent with what I usually think.
Ok, what about the side effects?
static SideEffect of(DeferredCall serviceCall, boolean synchronous) {
return new SideEffectImpl(serviceCall, synchronous);
}
static SideEffect of(DeferredCall serviceCall) {
return new SideEffectImpl(serviceCall, false);
}
I think we will have to keep supporting it.
In #673, Johan also mentions side effects. I agree that forward and side effects don't seem very useful inside entities, but at least we do not support async calls.