chennelPutGet VS channelRPC

EPICS v4 Working Group, Working Draft, 06-Mar-2014

Latest version:
putGetVSrpc.html
This version:
putGetVSrpc_20140306.html
Previous version:
putGetVSrpc_20140115.html
Editors:
Marty Kraimer, BNL

Abstract

Before union and unionArray were available channelRPC was the primary method for implementing services. This document makes the argument that channelPutGet should be considered for services where the argumment and/or result has an immutable introspection interface. If this argument is accepted then the information in this document should be moved into pvAccessJava.html.

Table of Contents

Introduction

A primary use of pvAccess is to implement network based services via a Remote Procedure Call (RPC) mechanism. pvAccess provides two ways to implement an RPC: channelPutGet and channelRPC.

For a channelRPC a client sends a top level PVStructure to the server, the service accepts the sructure, processes the request, and sends the result via another top level structure. The top level structures can be completely different for each request. A convention must be established about what introspection interfaces the service uses. This is the main purpose of normative types.

For a channelPutGet the service must create a PVRecord. A PVRecord has a record name, which is identical to the pvAccess channel name. The PVRecord has a top level PVStructure, which must have at least two PVStructure sub-fields: one for the put data for a request and one for the get data for the request. This the PVRecord has a top level PVStructure like the following:

structure 
     structure argument
        // service specific
     structure result
        // service specific
The client specifies the argument and the service specifies the result.

Before the types union and unionArray were available channelRPC was used for most services because the introspection interface for the result and/or the argument could change from request to request.

This document makes the argument that union and unionArray makes it possible to implement many services via channelPutGet instead of channelRPC. Using channelPutGet has the desirable feature that the other channel methods can also be used to access the PVRecord (channelRPC does not allow this). This allows the PVRecord to be introspected and montored, which are both desirable features.

NOTE: PVRecord is a concept implemented by pvDatabaseCPP and pvIOCJava. Each has a complete implementation of pvAccess channel provider. Thus implementing a service via channelPutGet assumes that a C++ service will use pvDatabaseCPP and a Java service will use pvIOCJava.

The next section shows how a PVRecord can be created that provides a channelPutGet that completele replaces a channelRPC. Next are some sections that provide additional examples. The last section is the summary.

PVRecord for channelPutGet that relaces channelRPC

The following is the introspection interface for the top level PVStructure for the PVRecord"

structure 
     structure argument
        any value
     structure result
        any value

Note that any is a union where the value can be any valid type and the type can change dynamically. This the above allows any type of data that channelRPC allows.

The only real advantage that this has over just using channelRPC is that the PVRecord can be monitored.

fixed type argument variable type result

The first example is:

structure 
     structure argument
        NTNameValue value
            string[] name
            string[] value
     structure result
        any value

The argument is normative type NTNameValue but the result can be any type. In additon to alowing requests to be monitored, this allows a client to discover and send acceptable arguments. This also allows for a generic tool for channelPutGet requests.

The next example allows that server to return variable data via a more restrictive union:

structure 
     structure argument
        NTNameValue value
            string[] name
            string[] value
     structure result
        union value
           string[] stringValue
           double[] doubleValue
           timeStamp[] timeStampValue
           alarm[] alarmValue

In this case the client can also discover what types the service can return.

fixed type argument fixed type result

This is what could have been done before union has available. Often channelRPC was used just because it the developer was familiar with implementing channelRPC. An example is:

structure 
     structure argument
        NTNameValue value
            string[] name
            string[] value
     structure result
        NTTable value
           string[] labels
           structure
                double[] value
                alarm[] alarm
                timeStamp[] timeStamp

Summary

The above gives some simple examples of how channelPutGet can be used instead of channelRPC. Implenting a service via channelPutGet requests rather than channelRPC allows the PVRecord to be monitored. Also channelGet can be used to see the most recent request. By thinking carefully of how to define argument and result, a service implementer can make more details about the service available to the client via introspection.