# Microservices

## Definitions
On of the main design abstractions in this project is the **microservices**.
Inspired by the area's seminal reference
(https://martinfowler.com/articles/microservices.html). "In short, microservice
architectural styles is an approach to developing a single application as a
suite of small services, [...] These services are built around business
capabilities and independently deployable [...]. There is a minimum of
centralized management of these services [...]." We use elements of this
approach in our design, not necessarily faithfully following it but using it as
an inspiration.  In a typical microservices-based application, the core is a
database. In our world, the ServerManager ends up acting as the database. It's
where the application's global state resides. Instead of the application logic
sitting in a monolithic core, as with ParaView, we leverage the microservices
principle to develop independent services to implement the business logic in
the visualization application.  microservices are stateless and lightweight.
There should be no dependencies between microservices. However, a microservice
can use another microservice internally by simply instantiating it.
microservices will expose their API using Observables. This design allows
enqueueing RPCs on the main event loop enabling the application to stay
responsive while the server component is processing the request.

## Examples
`vtkPTSPipelineBuilder`, a microservice to create and delete pipeline elements
like sources, filters, and representations.  `vtkPTSPipelineBuilder`
encapsulates all the steps required with the ServerManager to create pipeline
elements. This encapsulation includes initializing properties, registration
with the global object storage, etc.  Creating any pipeline element requires
querying and accessing our "database" the ServerManager module, so this method
is marks as `async` in the Python API and returns an `Observable` that will
emit a single value in the C++ API.

```python
    sphere = await builder.CreateProxy(
        "sources", "SphereSource", ThetaResolution=80, Radius=2
    )
```

`vtkPTSPipelineViewer`  gives access to the connectivity of the visualization
pipeline in an abstract and UI-independent manner.  In this case the
microservice will require to return a stream of values, one each time a
pipeline element is created or deleted.  Updates are consumed asynchronously by
returning an asynchronous iterator in the Python API:

```python
async def observer_pipeline(pipelineViewer):
    async for pipelineState in pipelineViewer.GetObservable():
        connectivity = []
        for item in pipelineState:
            # format items and add to connectivity as required
```
The C++ API returns an `Observable` that will emit a stream of values until the
microservice is destroyed  or `UnsubscribeAll()` is called.
