eigr / massa

A Stateful Serverless framework on the BEAM VM
https://eigr.io
Apache License 2.0
55 stars 5 forks source link

Proposal for Service Invocation #130

Open sleipnir opened 2 years ago

sleipnir commented 2 years ago

My proposal breaks a little bit of the initial premise of the CS protocol where the proxy acts as a client and the user function acts as a server, despite the communication being bidirectional originally, in fact the proxy starts and the user function responds with some information.

But I thought it would be difficult to reuse the original streamed semantics for a simple service invocation without having to force the sdks to implement it with callbacks or some kind of message buffer, which would make the whole flow very complex. So I chose to simplify and make the proxy also provide a service that could be called by the user function (again reversing the traditional flow) and would only play the function of orchestrator of the user function request.

Obviously this forces sdks to implement both a grpc server and a grpc client to communicate with the proxy. But that was a choice that Dapr followed and opened up so many paths for them. If there was an option to just keep streamed without it complicating things too much I'd take it, but I've thought a lot about the implications of streamed for things like invoking services and haven't been able to visualize how it could work without changing the structure of what was done.

sleipnir commented 2 years ago

The relevant part is in this commit here https://github.com/eigr/massa/pull/130/commits/f3f01180acbeb8cef91c1f39af333352bd2682ff

marcellanz commented 2 years ago

Thanks @sleipnir. I'll review it. I'm not sure yet if I understand all implications and how it would fit into the protocol, but I'm very much open for an interaction model where an SDK can be provided much simple than it is right now.

sleipnir commented 2 years ago

The big question that this proposal aims to answer is. How do I make direct invocations to other services (local or remote). Today the protocol doesn't have this mechanism besides an approximation with the Forward function.

Today what the customer can do is:

Client A invoke -> Service A -> Service A forward request to -> Service B -> Service B respond to Client A 

Which is good for some use cases and not good enough for other use cases. What we need to add in addition to Forwards would be:

Client A invoke -> Service A -> Service A invoke -> Service B -> Service B respond to Service A  -> Service A handle response, do  anything, maybe invoke other services, compile some response and respond to -> Client A

In other words, it gives us the ability to call other services without interrupting the flow of the original service. This, in addition to giving us greater coverage of different use cases, also opens the door to more complex state machine implementations, such as the implementation of the SAGA pattern (not covered in this PR) in the proxy.

Could I explain to you how things fit together?