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]


Reply via email to