Skip to main content

From outside your app

By "external" to a Reboot application, we mean from a (micro)service (e.g., a gRPC or HTTP based service) or a lambda (e.g., using some serverless framework), or even from your laptop! Your tests are another example of "external".

In order to call a method on an instance of your state externally, you'll need to use an ExternalContext, for example:

context = ExternalContext(
name="send message",
url="http://localhost:9991"
)

hello = Hello.ref(id)

response = await hello.Send(context, message="Hello, World!")

The url argument specifies where your Reboot application is running, e.g., on your laptop via rbt dev, in a container on Kubernetes via rbt serve (where url will likely route to your Kubernetes gateway), or in the cloud via rbt cloud.

Because an ExternalContext is used outside of Reboot, a series of Reboot methods called using an ExternalContext don't have any atomicity guarantees with regard to one another (although the individual methods executing within Reboot will of course still have their own atomicity). If you are calling multiple Reboot methods that you would like to happen atomically, you can move those calls into a transaction, and then call that method from your client.

Making calls idempotently

You can make calls idempotently() using an ExternalContext so that you only perform operations once. You can even pass an idempotency seed, e.g., a UUID, to an ExternalContext when constructing it so that every time you re-run code using that ExternalContext it will generate the same idempotency keys so that your external code will execute "where it left off" from the last time it was running. This is similar to trying to write code that idempotently converges, just external to your Reboot application. Here's an example:

context = ExternalContext(
name="send message",
url="http://localhost:9991",
idempotency_seed=uuid.UUID("123e4567-e89b-12d3-a456-426614174000"),
)

Calling readers reactively

Using an ExternalContext, you can also call reader methods reactively. For example:

fig = Fig.ref(fig_id)
async for response in fig.reactively().GetPosition(context):
print(f"{fig_id}: {response}")