brbzull0 opened a new pull request #8630:
URL: https://github.com/apache/trafficserver/pull/8630
### JSONRPC TS API proposal
This draft is based on https://github.com/apache/trafficserver/pull/7478
which holds the JSONRPC 2.0 implementation for ATS.
### Current state
Currently If a plugin wants to handle external messages they need to
implement the `TS_EVENT_LIFECYCLE_MSG` hook. This provides a one way only
message system for plugins, **plugins can only receive the message but cannot
respond to them directly**.
### Proposal
As a part of https://github.com/apache/trafficserver/issues/6633 we have
introduced https://github.com/apache/trafficserver/pull/7478 (not yet part of
ATS OS) which let traffic_server to receive and respond to external messages
using JSON as standard text-based format, following the JSONRPC 2.0 standard.
The goal of this proposal is to take advantage of this implementation and
let plugins be able to expose JSONRPC nodes(handlers) to the exterior and also
be able to respond directly to exterior clients(currently not possible).
To achieve this we are proposing to introduce a new set of API:
```c
typedef void (*TSRPCMethodCb)(const char *id, TSYaml params);
```
JSONRPC callback signature for method calls.
----
```c
typedef void (*TSRPCNotificationCb)(TSYaml params);
```
JSONRPC callback signature for notification calls
-------
```c
tsapi TSRPCProviderHandle TSRPCRegister(const char *provider_name, const
char *yamlcpp_lib_version);
```
Method to perform a registration and validation when a plugin is expected to
handle JSONRPC calls.
`param provider_name`: a string with the Plugin's description.
`param yamlcpp_lib_version`: a string with the yamlcpp library version. A
null terminated string is expected. Why do we need this? check _Binary
compatibility with YAMLCPP_ down below.
This function returns a new `TSRPCProviderHandle` or `nullptr` if the
`yamlcpp_lib_version` was not set or the yamlcpp version does not match with
the one used internally in TS. The returned `TSRPCProviderHandle` will be set
with the passed provider's name. The caller should pass the returned
`TSRPCProviderHandle` object to each subsequent
`TSRPCRegisterMethod/Notification` call.
----
```c
tsapi TSReturnCode TSRPCRegisterMethodHandler(const char *name,
TSRPCMethodCb callback, TSRPCProviderHandle info);
```
Add a new registered method handler to the JSON RPC server.
`param name`: Call name to be exposed by the JSONRPC server.
`param callback`: The function to be registered.
`param info`: `TSRPCProviderHandle` pointer, this will be used to provide
more context information about this call. This object
This function returns `TS_SUCCESS` if the handler was successfully
registered, `TS_ERROR` if the handler is already registered.
----
```c
tsapi TSReturnCode TSRPCRegisterNotificationHandler(const char *name,
TSRPCNotificationCb callback, TSRPCProviderHandle info);
````
Add a new registered notification handler to the JSON RPC engine.
`param info`: `TSRPCProviderHandle` pointer, this will be used to provide
more description to the RPC description. This object should be the one returned
by the `TSRPCRegister` API.
`param name`: Call name to be exposed by the JSONRPC server.
`param callback `: The function to be registered.
This function returns `TS_SUCCESS` if the handler was successfully
registered, `TS_ERROR` if the handler is already registered.
----
```c
tsapi TSReturnCode TSRPCHandlerDone(TSYaml resp);
```
Function to notify the JSONRPC server that the current handler is done
working.
This function must be used only when implementing a `method` JSONRPC
handler. Once the work is done and the response is ready to be sent back to the
client, this function should be called. Is expected to set the YAML node as
response. If the response is empty a `success` message will be added to the
client's response.
This function returns `TS_SUCCESS` if there are no issues. `TS_ERROR`
otherwise.
---
```c
tsapi TSReturnCode TSRPCHandlerError(int code, const char *descr);
```
Function to notify the JSONRPC server that the current handler is done
working and an error has arisen.
This should not be used if you registered your handler as a notification:
TSRPCNotificationCb call.
`param code`: Error code.
`param descr`: A text with a description of the error.
This function returns `TS_SUCCESS` if there are no issues. `TS_ERROR`
otherwise.
-----
Internals
This JSONRPC implementation is based on an iterative server(his own thread)
which handles a single request at a time, this blocks till the response is
handed back to the rpc server. For plugins this is a bit different as they need
the asynchronous style to deal with some specifics tasks, plugins needs to be
able to run tasks possibly on different thread and at a different time that
they get called to handle the JSONRPC call, so to achieve this the JSONRPC
server implements a notification mechanism(`TSRPCHandlerDone`,
`TSRPCHandlerError`) which will let the JSONRPC server that the plugin handling
is complete, either with an error or with a particular content. Plugins will be
able to reschedule the JSONRPC handling work as they see fit. You can find
examples in this PR.
### To be added into apidefs.h.in
```c
// JSONRPC 2.0 related interface.
typedef struct tsapi_rpcproviderhandle *TSRPCProviderHandle;
typedef struct tsapi_yaml *TSYaml;
```
### Binary compatibility with YAMLCPP
Having plugins with different version of YAMLCPP could be an issue, so as
with plugins, we cannot guarantee that a will be compatible across major
versions, so It would be feasible to only provide binary compatibility within
the lifespan of a major release, no new version of YAMLCPP should be introduced
in minor versions. Eventually plugins will need to recompile/link
### YAMLCPP version check
To help the plugin developers to spot issues, plugins should check-in
(using `TSRPCRegister`) with TS before registering any handler and validate
that their `yamlcpp` version is the same as used internally in TS. Plugins will
inform which version they have and internally we will compare this against the
one used in ATS (this could be an issue as we can use an external version of
YAMLCPP and not the one shipped with ATS)
See examples in this Draft PR.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]