Datatypes Models To Abeans Engine Mapping

Specification

Project:Abeans 
Identification:CSL-SPE-02-41
Status:Draft
Availability::Abeans//SPE-Datatypes_Models_To_Abeans_Engine_Mapping.xml
Creation:2002-05-18 (Gasper Tkacik)
Last Modification:2002-09-08 (Gasper Tkacik)
Copyright © 2002 by Cosylab d.o.o. All Rights Reserved.

Scope

This document contains description of mapping of all Datatypes based model method invocations into Requests submitted to Abeans Engine for delivery to the plug. More specifically, this document determines the target part of the Request, i.e. the transformation of the method invocation in the URI that specifies the target uniquely. An additional form is defined as well, which can be used to "serialize" or "stringitize" the whole request: an XML form conformant to the SOAP specification.

Audience

THe intended audience are developers that maintain, use, or extend the Abeans Engine or Abeans plugs.

Table of Contents

1. Introduction

2. Mapping Types

2.1. Basic URI Mapping

2.1.1. Scheme Part

2.1.2. Authority Part

2.1.3. Path Part

2.1.4. Query Part

2.1.5. Examples

2.1.6. Application Dependence on Plugs

2.2. XML SOAP Mapping

3. Case-by-Case Request Specifications

3.1. Dynamic Value Get Request

3.2. Dynamic Value Set Request

3.3. Dynamic Value Monitor Request

3.4. Characteristic Read Request

3.5. Dynamic Value History Request

3.6. Grouped Characteristic Read Request

3.7. Dynamic Value Asynchronous Get Request

3.8. Dynamic Value Asynchronous Set Request


Document History

1. Introduction

In Abeans Release 3, the data flow between the user of the framework and the underlying (possibly remote) system proceeds through Abeans Engine. Abeans Engine is an in-memory database that issues requests, processes them, forwards them to the plugs for execution on a specific communication system, receives the replies and forwards them to the user. In Release 3, Abeans support custom models, i.e. sets of interfaces that model or parametrize the sytem to which Abeans connect. Thus, for example, we know Channel model (where channel is defined as a dynamic value plus its characteristic context), BACI wide model etc. The user of the Abeans framework interacts directly with the model by invoking its methods. The model must communicate with Abeans Engine, ask it to issue requests, fill out the requests, submit them to the Abeans Engine database, wait for the replies and unpack them. The advantage of this approach is that all data flow must pass through Abeans Engine in the form of abeans.engine.Request and abeans.engine.Response instances. In this way, the data flow is well-defined and, moreover, additional processing can be done at the database layer, such as storing of reqeusts to permanent storage, indexing of requests, distributing reports for special requests or faulty responses and so on. To summarize: Abeans Engine narrows any kind of model down to the management of instances of two types, namely request and response, with fixed interfaces.

In order to better understand the relationships between parts of Abeans introduced above, the following interaction diagram should be of some help. The user is represented as invoking a getValue operation on an interface of the Channel model. This operation requests the value of a remote property to be queried by getting a Request instance from the Abeans database, setting up the request, and submitting it to the database. Independently of the Channel model the database must now use its threading and other policies to forward the request to the plug (which executes it by sending it to the remote server) and obtain a response. The response is then synchronously (in this example case) returned to the calling Channel.

Image: SPE-Datatypes_Models_To_Abeans_Engine_Mapping/channel-to-engine.png

Figure 1: The connection between Datatypes-based model (like Channel) and Abeans Engine.

Abeans put almost no restrictions on the nature of the model which communicates with the Engine and the interfaces that parametrize the model can take various forms. However, there is a subset of all models that we will discuss in this document, namely models that are based on the Cosylab Datatypes-Common project. Such models describe constructions known as properties, i.e. dynamic values (changeable value, like some physical parameter) in their characteristic contexts (static values describing the dynamic value, such as units, format, description etc). Usually, these models allow different kinds of accesses to dynamic value with regards to its Java type (e.g. access to dynamic value as double type, as int type etc.) or the access mode (synchronous access, asynchronous access, monitor access). Having so enumerated the capabilities of the Datatypes-Common based models, we can define the mapping of every possible access type in Datatypes-Common to a Request in the Abeans Enigne.

Each Request submitted to the Abeans Engine database has a property known as target. This is a string uniquely identifying the data source in the controlled system and the action that should be performed on that source. For example, a target PBEND_M.01/curent/minimum?get is a fictional target, that could specify that an operation get is to be invoked on the data source PBEND_M.01/current/minimum. Such target string might be generated when the user of the framework called method getMinimum() on an instance of DoubleChannel that is connected to the data source with name PBEND_M.01/current. Abeans designs are based on the premise that regardless of the model interfaces, the mapping of the interfaces to such target strings is always possible. This document defines such mapping for all Datatypes-Common based models.

2. Mapping Types

Two mappings of different types will be defined in this document. Firstly, a mapping of the all Datatypes-Common method invocations into target alone will be specified. The target in this case will follow the URI specifications of RFC 2396 and will be called simply "the mapping" or "basic mapping". The second mapping, called "XML mapping" or "SOAP mapping" will map a Request instance to an XML fragment, containing all data items needed to reconstruct from XML an identical request.

The purpose of the fist mapping is to have a consistent way of exchanging data between Abeans Engine and the plugs. If we follow external standards, it will be easy to create a wide variety of applications, such as web pages with dynamic content that access values just by specifying full target URIs. The parsers for URIs are a part of the standard Java 1.4 platform, as well. XML mapping is designed for request storage on the permanent media or for Web applications that exchange data directly with Abeans running as a server platform.

2.1. Basic URI Mapping

URIs defined in this document follow the hierarchical URI syntax, defined as:

[scheme:][//authority][path][?query][#fragment]

The mapping of Datatypes-Common and Abeans concepts to these parts is defined below.

2.1.1. Scheme Part

The scheme contains a general keyword that identifies the following URI as a part of the Abeans system. The keyword is equal to the Java package prefix of the Abeans, namely "abeans". To this, we append a separator character "-". After the separator, we specify the name of the plug that will handle the request, for example "TINE". The scheme part is therefore composed of Abeans identifier and plug identifier, which is correct, since each pluggable system has a specific way of binding of names to remote data sources.

2.1.2. Authority Part

Abeans interface abeans.models.Connectable parametrizes an entity that can be connected, i.e. that can have its string name resolved into the connection to the remote data source. This name resolution is performed within the scope of the name service offered by the underlying controlled system. There may be one such naming service (one well-defined namespace), zero such naming services (global namespace) or many naming services. If a naming service exists, the authority part must contain its unique identification. The interpretation of such identification is left to the plug. The identification, as per RFC, extends to the first slash '/' character after double slash '//' prefixing the authority part. For example, an authority might be a server name cheka.ijs.si:3000, where the naming service runs. If there are zero naming services, the authority part is empty, and the name is a global name. In this case, scheme is followed by a semicolon and triple slash '///'.

2.1.3. Path Part

Path part does not depend on the pluggable system. It is composed of the name of the Connectable instance, which the authority part can resolve, and with path name that specifies the desired data source within that connectable. In Channel model, where Channels directly implement Connectable, the first part of the name is directly the channel name. In other models, where Datatypes-Common interfaces are not directly implemented by Connectable types (like in BACI, where a Device is a Connectable, but a Property only a Linkable), the first component of the name must be the device name. If no other path component is present after the name of the Datatypes-Common property, the target path formed by such URI represents directly the dynamic value of that property. If other path components are specified after the property name, they must be separated from the property name by URI hierarchy separators, namely slash '/' characters. Such further path components refer to data sources inside the property, which may be - as per Datatypes-Common specifications - characteristics or asynchronous mode invocations.

A characteristic is a name-value pair. It can either be declared statically in the implementing class of Datatypes-Common interface as a JavaBeans property, or it may be dynamic, accessible during run-time through name-value lookup. In the first case the name of the characteristic is implied from the JavaBeans design pattern, where accessor methods conform to the prototype

					  <characteristic_type> get<characteristic_name>() throws DataExchangeException
					  
					
Listing 1: Characteristic accessor design pattern.

In the second, dynamic case, the property names are defined as static final constants in either Datatypes-Common libraries, or, additionally, in their Abeans extensions in abeans.datatypes. When implementing a new model or a new plug, a characteristic name already defined must be used. Only if a name does not exist for the characteristics of a given function, may a new name be introduced.

Asynchronous operations can be declared by types that implement the AsynchronousMode interface from the Datatypes-Common project. The method signature for the asynchronous operations is as follows:

					  Request <operation_name>(<operation_parameters>) throws DataExchangeException
					  
					
Listing 2: Asynchronous operation design pattern.

In short, asynchronous operations return instances of their Request objects, which may be used to track the progress of the operation. The name of the asynchronous operation is simply its method name.

In this way, both characteristic and asynchronous operation names are well defined. In conclusion, it is possible to form a unique name identifying either a characteristic or an asynchronous action, by suffixing it to the property name.

2.1.4. Query Part

A query part provides parameters that further qualify the target, where this is needed. In Datatypes-Common compliant model implementations, such as BACI model or Channel model, the query is, in basic mapping, defined only for the target specifications that name the dynamic value directly. When this is the case, the following query parts are defined:

QueryDescription
getThe target represents a query for the dynamic value, which must be sent as a response.
setThe target represents a request for the dynamic value to be set.
monitorThe target represents a request for the monitor to be created on the dynamic value.

Table 1: Possible query strings when the target names the dynamic value.

2.1.5. Examples

This section provides some URIs in the simple mapping, which are constructed according to the guidelines described above. XML mapping will contain the URI mapping and, in addition, all the parameters that parametrize a Request. The reason in short is that in XML mapping, the XML must contain the complete request data (along with the expected timeouts, parameters, properties, blocking modes etc. as defined in the Request documentation), whereas in simple mapping all those additional data items are programatically present in the Request object.

As an example, we will work with channel implementation of the Datatypes-Common model. In this implementation, Channel instances are Connectables and are top-level objects that can be resolved from string names. Let our channel name be PBEND_M_01_current. Let us also assume, that there is no name resolution authority, such as is the case with EPICS, and that the model is communicating through the plug named EPICS. Then

abeans-EPICS:///PBEND_M_01_current?get

will request the value of the channel to be read, whereas

abeans-EPICS:///PBEND_M_01_current?set

will generate a set request in the plug, and

abeans-EPICS:///PBEND_M_01_current?monitor

will start a new monitor on the dynamic value.

In case of TINE, the situation is a bit different. TINE supports hierarchical naming and also has dedicated name servers. The syntax for reading the dynamic value then changes into:

abeans-TINE://ns.desy.de/DESY/BENDS/PBEND_M_01/current?get

In this case, the naming authority is specified and the path to the correct Channel ("current") is thorugh TINE Namespaces (i.e. context, server, device).

To read a characteristic, its name is appended after the property (dynamic value) name, in the following manner:

abeans-EPICS:///PBEND_M_01_current/minimum?get

Query flags are not needed, since characteristics are only read. In the same way asynchronous operations can be executed, where the default operation on the asynchronous operation data source is its execution.

2.1.6. Application Dependence on Plugs

If URI strings like the above examples are hardcoded into applications, two problems may arise:

  • Strings of unreadable length. Specifying the plug type and the name service authority in each request can be time-consuming, error prone and simply annoying, especially in the cases where the whole application uses a single plug and there is only one name authority.
  • High level of plug dependence. If plug names are explicitly hardcoded in many parts of the application, the application may be difficult to port to another plug, even if the models match.

To address these issues, Abeans do not by default specify the targets by URIs, but through abeans.pluggable.RemoteInfo instances. These instances specify the plug type as a separate string field and do not specify the name authority. The plug type can be left unset, in which case it defaults to the single plug used by the application. If multiple plugs are used by the application and the plug type is not specified, this will cause an exception to be thrown. The same principle applies to the name authority. To summarize: the RemoteInfo contains, as its name field, only the path?query part of the full URI specification. Implementations of RemoteInfo interface must be able to generate the full form URIs according to the syntax presented here.

The database and the plug, however, must be able to process full URI target specifications of the above format.

With this approach, multi-plug, multi-name-authority applications are still possible, while simplicity is retained for single-plug, single-name-authority applications. Moreover, the URIs are not visible from the model layer at all, because they are handled internally by Abeans. Consequently the dependence of the application on the underlying pluggable system reduces to the dependence on the structure of the path component, which cannot be generalized. But even for this problem there exists a solution in terms of mapping tables, that exist in the plug. Two Channel applications running on different plugs, A and B, naturally differ in their channel names. However, if one of the plugs (say A) maps the names of plug B into its own names, the same applications can run without modification on different plugs.

2.2. XML SOAP Mapping

3. Case-by-Case Request Specifications

This section defines request structures for different operations that are allowed within the Datatypes-Common framework and consequently within all Abeans models that are based on this framework. For each type of interaction of the model and the database, the request fields and their mandatory or optional values are presented here.

3.1. Dynamic Value Get Request

The following table lists the request structure for the dynamic value get operation:

FieldValue
targetURI that names dynamic value directly, with ?get query part.
blockingValues true or false depending on user setting. This does not influence the plug execution but only how database processes the requests.
errorMay be set by the plug to denote that the request execution has failed. Must be examined by the model or the framework user.
parametersMust be null.
timeoutDeltaMay be set by the plug before the request is sent to the remote layer. In this case the database will expect a new response in delta period.
proxyMust not be set by the plug.
propertiesProperties not understood by the plug must be ignored. The following properties must be supported:
  • type Value: A ResponseType object specifying the type in which the dynamic value must be delivered in Response.

Table 2: Request structure for dynamic value get.

When this request is received by the plug, the plug must immediately respond by calling back database with message requestStarted. When the return value is obtained from the remote layer, the plug must use the RequestResponseFactory interface to create a new Response, set the error and completion fields, leave the qualifier field empty, and insert a new value into the Response. The response must be of the ResponseType type. The plug finally performs Request.addResponse() to add a new response to the request and invokes requestNewResponse callback on the database. This finishes the processing of the request.

			  
getDatabase().getRequestCallback().requestStarts(r);
Response rp = createResponseForType(r, type, ctype, ccode, System.currentTimeMillis());
rp.setValueAsObject(getValue());
getDatabase().getRequestCallback().requestNewResponse(rp);
			  
			
Listing 3: Code snippet for dynamic value get in plug implementation. The first line tells the database that the request has started to execute. The second line creates the response with specified data type, completion type completion code and time. The third line inserts the dynamic value into the response. The fourth line submits the response back into the database. Because the request is SINGLE, the submittal of new response will also terminate the request.

The model will submit this request as a RequestType.SINGLE_REQUEST, which means that the first response is also the last response and that the request automatically terminates when the first response is received.

3.2. Dynamic Value Set Request

The request structure is the same as in Dynamic Value Get Request, but with the following differences:

FieldValue
targetURI that names the dynamic value directly, with ?set query part.
parametersMust be of type Object[] of length exactly 1. The element at index 0 must be either a primitive Java wrapped appropriately or an object according to the type property specified in the request properties.

Table 3: Request structure for dynamic value set.

The plug confirms the request execution by submitting back an instance of Request with no value and calling back the database.


getDatabase().getRequestCallback().requestStarts(r);
Object[] params = r.getParameters();
if (type.equals(Double.TYPE)) // type casts check type correctness
{
	setValue((Double)params[0]);
} else if (type.equals(Integer.TYPE))
{
	setValue((Integer)params[0]);
} else if (type.equals(Long.TYPE))
{
	setValue((Long)params[0]);
} else
{
	setValue(params[0]);
}
Response rp = getDatabase().getRequestResponseFactory().createResponse(ResponseType.VOID, r, ctype, ccode, System.currentTimeMillis());
r.addResponse(rp);
getDatabase().getRequestCallback().requestNewResponse(rp);
			  
			
Listing 4: Code snippet for implementation on the plug layer of dynamic value set. First, we inform the database that request processing has begun. Then we extract the parameters from the request; we demand that there is one parameter of the proper type. We create response and populate it with completion code, type and time. The response is of type void, because it does not carry any return value. The last line terminates the request by submitting a single response.

3.3. Dynamic Value Monitor Request

Monitor is different from other kinds of requests in that it:

  • it is not a RequestType.SINGLE_REQUEST. It is a RequestType.REPEATED_REQUEST, which means that for a single submitted request, many responses can be produced by the plug. Each time a plug receives (or polls for) a new value on the remote system, it must insert a new response with Request.addResponse and notify the database through the callback. When the request ends (either because user requests so or for other reasons), the plug must explicity invoke requestEnds notification on the database callback.
  • causes the creation of transient proxy object. Monitor allocates some resources within the plug which have a lifetime longer than that of the single request invocation, i.e. such resources exist across several response arrivals. On one hand, the plug itself maybe wants to store some information connected with such request, and the Request.setProxy() offers a way of doing it. On the other hand, the model may wish to control the monitor behaviour. This it can do, because the model may prescribe that such a proxy must extend a certain interface, for example abeans.models.channel.MonitorProxy interface.

The proxy mechanism works as follows:

  1. The model layer creates a new REPEATED_REQUEST. It fills out the fields outlined below, including the callback field through which responses will be received. If the model decides that the monitoring is controllable through abeans.datatypes.Monitor interface, the model creates an instance of type that implements this interface. By design, this instance also implements the abeans.models.Linkable interface and the link will be established when such monitor receives an instance of MonitorProxy.
  2. The request is submitted to the database. Database forwards it to the plug. The plug creates an instance implementing MonitorProxy when it creates resources necessary for the monitor to run. The plug then informs the database through the callback method requestStarts.
  3. The model layer receives the requestStarts and picks out from the request the proxy by calling Request.getProxy(). With this proxy it initializes the Monitor by calling Monitor.initialize(proxy). Because monitor is linkable, it will fire LinkEvents to all listeners: now the monitor values will start comming and it is possible to control the monitor by invoking methods on the Monitor.
  4. Whenever the user calls a method on the Monitor (for example a method to change the timer trigger), the same method is called on the MonitorProxy which was created by the plug. The plug can thus respond to the method by appropriatelly adjusting the monitor.
  5. When the user calls Monitor.destroy(), the model implementation will call destroy method on the proxy and, in addition, submit a stopRequest to the database to make sure that the monitoring ends and that all transient objects are released. All further invocations on the MonitorProxy instance must fail.

Image: SPE-Datatypes_Models_To_Abeans_Engine_Mapping/monitor.png

Figure 2: Interaction diagram that shows monitor creation.

Apart from the seemingly complex interaction diagram, the request structure for the monitor is relatively simple:

FieldValue
targetURI that names dynamic value directly, with ?monitor query part.
blockingValue true does not make sense in this case although it is possible. Should be false.
errorMay be set by the plug to denote that the request execution has failed. Must be examined by the model or the framework user.
parametersMust be null.
timeoutDeltaMay be set by the plug before the request is sent to the remote layer. In this case the database will expect a new response in delta period. This checks the regular arrival of new responses. The plug should probably set this value to some multiple of the monitor's timerTrigger.
proxyMust be set by the plug, as explained above, before requestStarted callback is sent to the database. The proxy implementation is maintained by the plug and must be functioning during the lifetime of the monitor (until the user destroys it or the monitor fails for some reason).
propertiesProperties not understood by the plug must be ignored. The following properties must be supported:
  • type Value: A ResponseType object specifying the type in which the dynamic value must be delivered in Response.

Table 4: Request structure for dynamic value monitor.

3.4. Characteristic Read Request

The request structure is the same as in Dynamic Value Get Request, but with the following differences:

FieldValue
targetURI that names the dynamic value, plus a hierarchy separator '/' plus the characteristic name plus '/' plus get query.

Table 5: Description of the table

The plug adds a new response with the characteristic's value (of type type specified in Request.getProperties()) and calls back the database, which completes the request. The code snippet for the characteristic get is basically similar to the dynamic value get.

3.5. Dynamic Value History Request

History request is a single request, which, similarly to a monitor request, results in a creation of a transient object in the pluggable layer. Therefore the proxy mechanism is used, in a similar fashion to monitors. History request is submitted in response to an invocation of a method declared in Datatypes HistoryAccess interface:

			
public interface HistoryAccess 
{
	HistoryIterator getHistory(HistoryConstraints hc) throws DataExchangeException;
}

public class HistoryConstraints
{
	...
	public long	getStartTime();
	public long	getStopTime();
	public int	getMaximumHistoryElements();
	public String	getHistorySource();
	...
}
			
			
			
Listing 5: Two Datatypes entities: the getHistory() implementation in Abeans will submit a history response to the Abeans Engine. The returned object of type HistoryIterator represents a Linkable Abeans entity (the actual runtime type is AbeansHistoryIterator that extends the HistoryIterator and Linkable). This object (because it is Linkable) is initialized with proxy of type HistoryIteratorProxy instantiated by the plug - this represents the transient object created in the pluggable layer. The history constraints object is supplied as a parameter to getHistory() and gets mapped into request properties as described below.

The proxy mechanism works as follows:

  1. The model layer creates a new SINGLE_REQUEST with history query target. It fills out the fields outlined below. For callback it provides an instance of abeans.engine.StartRequestLock that will block until requestStarts notification is received after submitting the request. Modeling layer instantiates a type implementing abeans.datatypes.AbeansHistoryIterator interface. By design, this instance also implements the abeans.models.Linkable interface and the link will be established when such iterator receives an instance of HistoryIteratorProxy.
  2. The request is submitted to the database. Database forwards it to the plug. The plug creates an instance implementing HistoryIteratorProxy when it creates resources necessary for the history query to run. The plug then informs the database through the callback method requestStarts.
  3. The model layer receives the requestStarts and deblocks. It picks out from the request the proxy by calling Request.getProxy(). With this proxy it initializes the AbeansHistoryIterator by calling AbeansHistoryIterator.initialize(proxy). The history iterator is now ready to be returned to the users and used.
  4. Whenever the user calls a method on the HistoryIterator (for example a method get the history data items), the appropriate method is called on the HistoryIterator which was created by the plug. The plug can thus respond to the method by taking the appropriate action for that method (for example querying the history data items from the archive server).
  5. When the user has retrieved all data items from the history iterator, the iterator will dispatch requestEnds notification to the database, All further invocations for more data on history iterator return empty values, the transient proxy implementation of the pluggable layer can be released.
FieldValue
targetURI that names dynamic value directly, with ?history query part.
blockingShould be false.
errorMay be set by the plug to denote that the request execution has failed. Must be examined by the model or the framework user.
parametersMust be null.
timeoutDeltaSet to 0. Iterator finishes whenever user empties all history data elements, which can happen at whatever time. If this value is set, however, the lifetime of the history iterator will be limited (i.e. a timeout will end the request and destory the proxy). This may sometimes be desirable behavior, if the resources must be freed.
proxyMust be set by the plug, as explained above, before requestStarted callback is sent to the database. The proxy implementation is maintained by the plug and must be functioning during the lifetime of the history iterator (until the iterator is emptied).
propertiesProperties are a direct mapping from HistoryConstraints into map form: for every Java Beans property with name X and the accessor HistoryConstraints::getX(), there is an entry with name "X" in the properties map, and the value of the history constraints property.

Table 6: Request structure for dynamic value history request.

3.6. Grouped Characteristic Read Request

3.7. Dynamic Value Asynchronous Get Request

The following table lists the request structure for the asynchronous dynamic value get operation:

FieldValue
targetURI that names dynamic value directly, with ?get_async query part.
blockingValues true or false depending on user setting. This does not influence the plug execution but only how database processes the requests. Setting this to true will probably not make any sense although it is possible (have the client block while the request is dispatched in an asynchronous way).
errorMay be set by the plug to denote that the request execution has failed. Must be examined by the model or the framework user.
parametersMust be null.
timeoutDeltaMay be set by the plug before the request is sent to the remote layer. In this case the database will expect a new response in delta period.
proxyMust not be set by the plug.
propertiesProperties not understood by the plug must be ignored. The following properties must be supported:
  • type Value: A ResponseType object specifying the type in which the dynamic value must be delivered in Response.
  • async Value: A boolean set to true.

Table 7: Request structure for asynchronous dynamic value get.

When this request is received by the plug, the plug must immediately respond by calling back database with message requestStarted. Then, the plug must dispatch the request to the remote layer in such a way so as not to block the calling thread. In other words, the plug must not wait for the response from the underlying data source, but must provide a callback and return as soon as possible. When the return value is obtained from the remote layer, the plug must use the RequestResponseFactory interface to create a new Response, set the error and completion fields, leave the qualifier field empty, and insert a new value into the Response. To reiterate: response construction does not occur in the thread in which the request was submitted. The response must be of the ResponseType type. The plug finally performs Request.addResponse() to add a new response to the request and invokes requestNewResponse callback on the database. This finishes the processing of the request.

Apart from the threading issues, the behavior of the value asynchronous get is the same as the behavior of the syncrhonous (normal) get.

The model will submit this request as a RequestType.SINGLE_REQUEST, which means that the first response is also the last response and that the request automatically terminates when the first response is received.

3.8. Dynamic Value Asynchronous Set Request

The following table lists the request structure for the asynchronous dynamic value get operation:

FieldValue
targetURI that names dynamic value directly, with ?set_async query part.
blockingValues true or false depending on user setting. This does not influence the plug execution but only how database processes the requests. Setting this to true will probably not make any sense although it is possible (have the client block while the request is dispatched in an asynchronous way).
errorMay be set by the plug to denote that the request execution has failed. Must be examined by the model or the framework user.
parametersMust be an Object[] of length 1, with the first parameter (index 0) containing the value to be set.
timeoutDeltaMay be set by the plug before the request is sent to the remote layer. In this case the database will expect a new response in delta period.
proxyMust not be set by the plug.
propertiesProperties not understood by the plug must be ignored. The following properties must be supported:
  • type Value: A ResponseType.VOID.
  • async Value: A boolean set to true.

Table 8: Request structure for asynchronous dynamic value set.

When this request is received by the plug, the plug must immediately respond by calling back database with message requestStarted. Then, the plug must dispatch the request to the remote layer in such a way so as not to block the calling thread. In other words, the plug must not wait for the response from the underlying data source, but must provide a callback and return as soon as possible. When the return value is obtained from the remote layer, the plug must use the RequestResponseFactory interface to create a new Response, set the error and completion fields, leave the qualifier field empty, and insert a new value into the Response. To reiterate: response construction does not occur in the thread in which the request was submitted. The response must be of the ResponseType type. The plug finally performs Request.addResponse() to add a new response to the request and invokes requestNewResponse callback on the database. This finishes the processing of the request.

Apart from the threading issues, the behavior of the value asynchronous get is the same as the behavior of the syncrhonous (normal) get.

The model will submit this request as a RequestType.SINGLE_REQUEST, which means that the first response is also the last response and that the request automatically terminates when the first response is received.

Document History

RevisionDateAuthorSectionModification
1.02002-05-18Gasper TkacikallCreated.
1.12002-05-27Gasper Tkacik3.Added code snippets for requests and responses.
1.22002-08-10Gasper Tkacik2.1.5.Correction: characteristic read request targets also end with "?get" query.
3.5.Added details about history query.
1.32002-09-08Gasper Tkacik3.7.Added asynchronous get specification.
3.8.Added asynchronous set specification.
Image: ../../images/Cosylab.png