Abstracting backend modules

A remote procedure call in DASF happens via a single message to the endpoint where the server stub is listening to, i.e. the topic at the message broker.

To call the hello_world function of our example code, for instance, the consumer expects the following payload in a message sent to the topic:

{
    "func_name": "hello_world",
    "name": "Peter"
}

Obviously the "func_name" corresponds to the name of the function to call, and the remaining parameters (here only "name") are the input for the function.

After this section we describe in more details

  1. how we decide what procedure is available for the RPC call (i.e. what the valid values for "func_name" is, see Specifying module members)

  2. how we verify that the request is a valid request for the procedure that should be called via RPC (see Abstracting procedures).

But let us anticipate the final result: What we end up with is one single pydantic root model[1] that represents the models of the individual procedures (aka functions and classes in the backend module).

Our main() function that we use in our example code is in fact only a shortcut that equips the create_model() classmethod of the BackendModule class with a command-line interface. The purpose of this function is to create a subclass of the BackendModule that accepts our request from above, and is able to map it to the hello_world function.

In our example code, the resulting model for the backend module, the HelloWorldBackendModule, is comparable to

from demessaging.backend import BackendModule, BackendFunction
from typing import Literal

class HelloWorldModel(BackendFunction):

    func_name: Literal["hello_world"] = "hello_world"
    name: str

class HelloWorldBackendModule(BackendModule):

    root: HelloWorldModel

and our hello_world function can be called with

# create the model
model = HelloWorldBackendModule.parse_json("""
{
    "func_name": "hello_world",
    "name": "Peter"
}
""")
# call the function
assert hello_world("Peter") == model()

But, let’s now start with understanding, how we select the members for the remote procedure call.