theia-trace-extension icon indicating copy to clipboard operation
theia-trace-extension copied to clipboard

Update ADR 0011-tsp-analysis-api for custom analysis

Open bhufmann opened this issue 1 year ago • 3 comments
trafficstars

Update 0011-tsp-analysis-api for custom analysis

  • Introduce action endpoint and data structures for outputs
  • Add example use case realizations using new API
  • Use global configuration endpoint to manage data provider configs

Signed-off-by: Bernd Hufmann [email protected]

bhufmann avatar May 27 '24 13:05 bhufmann

I would like to suggest a simpler solution as a stepping stone. I believe having a Configuration service at the data provider level would suffice to create customized derived data providers. We can probably live without actions in that case. Configuration and Derived Data Providers would be independent objects, and have independent life cycles.

  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config/types Returns a list of configuration source types: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)

  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config/types/{typeId}
    Returns a single configuration source type for given typeId: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)

  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config/types/{typeId}/configs Returns a list of configuration instances for a given data provider for a give typeId

  • POST /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/configs Upload a configuration definition for given data provider of a give typeId. Returns a new configuration descriptor with unique configuration ID

  • PUT /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/configs/{configId} Update a configuration

  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/configs/{configId} Returns the configuration descriptor for given configId

  • DELETE /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/config/{configId} Delete a configuration instance

  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config Return a structure of configuration instances (with their types) for a given data provider (of all types)

  • POST /experiments/{expUUID}/outputs/timeGraph/{outputId} Returns a Derived Data Provider with a unique Derived Output ID Parameter must include configId

  • PUT /experiments/{expUUID}/outputs/timeGraph/{outputId}/{derivedOutputId} Update a Derived Data Provider

  • DELETE /experiments/{expUUID}/outputs/timeGraph/{outputId}/{derivedOutputId} Delete a Derived Data Provider

  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId} Include the list of Derived data providers in the returned parent data provider descriptor

This approach is obviously limiting, but is simpler and easy to design and implement for the basic use case of enabling Customized data providers. Configuration service at global and experiment level may help with reuse of configs and allow many other use cases. But they also increase the scope of the problem. It would be nice to have Global and experiment level config services, but I would suggest that they be deferred for later as a follow-up.

abhinava-ericsson avatar Jun 28 '24 18:06 abhinava-ericsson

I would like to suggest a simpler solution as a stepping stone. I believe having a Configuration service at the data provider level would suffice to create customized derived data providers. We can probably live without actions in that case. Configuration and Derived Data Providers would be independent objects, and have independent life cycles.

  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config/types Returns a list of configuration source types: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config/types/{typeId} Returns a single configuration source type for given typeId: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config/types/{typeId}/configs Returns a list of configuration instances for a given data provider for a give typeId
  • POST /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/configs Upload a configuration definition for given data provider of a give typeId. Returns a new configuration descriptor with unique configuration ID
  • PUT /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/configs/{configId} Update a configuration
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/configs/{configId} Returns the configuration descriptor for given configId
  • DELETE /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/config/{configId} Delete a configuration instance
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config Return a structure of configuration instances (with their types) for a given data provider (of all types)
  • POST /experiments/{expUUID}/outputs/timeGraph/{outputId} Returns a Derived Data Provider with a unique Derived Output ID Parameter must include configId
  • PUT /experiments/{expUUID}/outputs/timeGraph/{outputId}/{derivedOutputId} Update a Derived Data Provider
  • DELETE /experiments/{expUUID}/outputs/timeGraph/{outputId}/{derivedOutputId} Delete a Derived Data Provider
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId} Include the list of Derived data providers in the returned parent data provider descriptor

This approach is obviously limiting, but is simpler and easy to design and implement for the basic use case of enabling Customized data providers. Configuration service at global and experiment level may help with reuse of configs and allow many other use cases. But they also increase the scope of the problem. It would be nice to have Global and experiment level config services, but I would suggest that they be deferred for later as a follow-up.

Bernd brought up the issue of code and API duplication due to sub-services. We can change the approach to remove "timegraph" (or XY, data, table etc) from the URI. Also, we can choose to not create configs as a resource, because its lifecycle is logically tied to the derived data provider. This would simplify the API too. The resultant service and API updates would look like:

  • GET /experiments/{expUUID}/outputs/{outputId}/configTypes Returns a list of configuration source types: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)
  • GET /experiments/{expUUID}/outputs/{outputId}/configTypes/{typeId} Returns a single configuration source type for given typeId: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)
  • POST /experiments/{expUUID}/outputs/{outputId} Returns a Derived Data Provider with a unique Derived Output ID It should contain the configuration to allow manual reuse Parameter must include typeId and config adhering to the typeId
  • DELETE /experiments/{expUUID}/outputs/{outputId}/{derivedOutputId} Delete a Derived Data Provider
  • GET /experiments/{expUUID}/outputs/{outputId} Include the list of Derived data providers in the returned parent data provider descriptor (To allow grouping of data providers) *We may choose to implement this in a different way.

abhinava-ericsson avatar Jul 11 '24 17:07 abhinava-ericsson

I would like to suggest a simpler solution as a stepping stone. I believe having a Configuration service at the data provider level would suffice to create customized derived data providers. We can probably live without actions in that case. Configuration and Derived Data Providers would be independent objects, and have independent life cycles.

  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config/types Returns a list of configuration source types: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config/types/{typeId} Returns a single configuration source type for given typeId: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config/types/{typeId}/configs Returns a list of configuration instances for a given data provider for a give typeId
  • POST /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/configs Upload a configuration definition for given data provider of a give typeId. Returns a new configuration descriptor with unique configuration ID
  • PUT /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/configs/{configId} Update a configuration
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/configs/{configId} Returns the configuration descriptor for given configId
  • DELETE /experiments/{expUUID}/outputs/timeGraph/{outputId} /config/types/{typeId}/config/{configId} Delete a configuration instance
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId}/config Return a structure of configuration instances (with their types) for a given data provider (of all types)
  • POST /experiments/{expUUID}/outputs/timeGraph/{outputId} Returns a Derived Data Provider with a unique Derived Output ID Parameter must include configId
  • PUT /experiments/{expUUID}/outputs/timeGraph/{outputId}/{derivedOutputId} Update a Derived Data Provider
  • DELETE /experiments/{expUUID}/outputs/timeGraph/{outputId}/{derivedOutputId} Delete a Derived Data Provider
  • GET /experiments/{expUUID}/outputs/timeGraph/{outputId} Include the list of Derived data providers in the returned parent data provider descriptor

This approach is obviously limiting, but is simpler and easy to design and implement for the basic use case of enabling Customized data providers. Configuration service at global and experiment level may help with reuse of configs and allow many other use cases. But they also increase the scope of the problem. It would be nice to have Global and experiment level config services, but I would suggest that they be deferred for later as a follow-up.

Bernd brought up the issue of code and API duplication due to sub-services. We can change the approach to remove "timegraph" (or XY, data, table etc) from the URI. Also, we can choose to not create configs as a resource, because its lifecycle is logically tied to the derived data provider. This would simplify the API too. The resultant service and API updates would look like:

* GET /experiments/{expUUID}/outputs/{outputId}/configTypes
  Returns a list of configuration source types: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)

* GET /experiments/{expUUID}/outputs/{outputId}/configTypes/{typeId}
  Returns a single configuration source type for given typeId: typeId, name, description, scope, expected parameter descriptors (e.g. "path" for file path)

* POST /experiments/{expUUID}/outputs/{outputId}
  Returns a Derived Data Provider with a unique Derived Output ID
  It should contain the configuration to allow manual reuse
  Parameter must include typeId and config adhering to the typeId

* DELETE /experiments/{expUUID}/outputs/{outputId}/{derivedOutputId}
  Delete a Derived Data Provider

* GET /experiments/{expUUID}/outputs/{outputId}
  Include the list of Derived data providers in the returned parent data provider descriptor (To allow grouping of data providers) *We may choose to implement this in a different way.

Thanks for the design discussions and providing suggestions for the TSP API to create views (outputs) based on a configuration.

I think it makes sense to use a POST on the output endpoint to create new outputs. That's a common practice for such APIs. The same thing is valid for DELETE. Allowing for different types which boils down to different input parameters needed for the creation of outputs, gives the back-end some flexibility for customizations. This approach we can use, for example, configure critical path output from the thread status view, create custom charts from the events table as well as create parametrized views (i.e. same domain-specific view but with different parameters).

Since we limit the scope to creating views (outputs) from another view (output), it should speed-up the implementation of this enhancement. Other use cases (e.g. other types of configurations of experiments) can be handled separately.

I'll give other people in community a couple of days to comment, and then I'll update the ADR based on this discussion.

bhufmann avatar Jul 15 '24 17:07 bhufmann

Thanks for all the feedback.

bhufmann avatar Aug 26 '24 20:08 bhufmann