Hi folks, I’m thinking about creating a general “Auto RPC” adaptor, and I wonder how the community think about this idea – is it feasible, is it a good practice, should I make this an open source contrib, etc.
The context is that I’m moving a monolithic application towards a distributed microservice architecture, and one task is to expose “MyDataStore” class as a microservice so that operations on the local datastore can be invoked remotely (RPC). As many of you may already feel, a Temporal workflow resembles a RPC method in many ways: clearly defined contract; serializable input/output type; can be executed from anywhere that’s connected to temporal cluster.
So I’ve found a way to make it really easy to adapt Temporal as a microservice platform, simply by
adding a @activity.defn to the method that I want to expose, e.g.:
class MyDataStore:
@activity.defn(name='MyDataStore.do_this')
def do_this(self, input: InputType, ...) -> OutputType:
...
Then, I write a generic workflow that executes a single activity
@workflow.defn
class GenericSingleActivityWorkflow():
@workflow.run
def run(self, rpc_method: str, *args):
return await workflow.execute_activity(rpc_method, args=args, ...)
Then I generate a client stub class, i.e., a subclass of MyDataStore class that intercepts method invocation and forward to execute this GenericSingleActivityWorkflow passing method name and args. BTW, I used the activity._Definition
class to check if the method has @activity.defn decorator.
This has worked pretty well. Now that I’m re-thinking about my prototype, I realize it can be made much simpler as a general extension to Temporal, making it a general microservice platform, e.g.:
@auto_rpc_service
class MyDataStore:
def _priviate_method(...)
@auto_rpc_method
def public_rpc_method(...)
# "Worker" == "Server"
store = MyDataStore(...)
worker = auto_rpc_service.create_worker(store, worker_config)
worker.run()
# Client stub can be auto-generated
my_data_store_client = auto_rpc_service.client_stub(MyDataStore, temporal_client)
my_data_store_client.public_rpc_method(...)