004 Data client threading model
- Status: accepted
- Deciders: partners
Context and Problem Statement
Most NC/PLC/Sensor communication involves network communication which is inherently asynchronous. There are however existing communication libraries for some of the communication targets which only support blocking synchronous calls.
To be able to support both types of communication we need to select a threading model for data clients which makes it equally easy to implement synchronous and asynchronous data clients.
The selected threading model is intended to be used by data client wrapper
implementations for encapsulating access to data clients.
Hint: The requirements concerning file/block transfer, events and methods have to be evaluated separately.
Decision Drivers
- supportability: data clients can be easily implemented by a sensor/tool manufacturer
- reusability: data clients can be integrated into different TE implementations
- flexibility: async and sync data clients must be supported
Decision Outcome
Async data client API
Pros and Cons of the Options
Single threaded access
Data clients can only be accessed in a single thread.
- Good, because data clients can be implemented more easily
- Good, because async calls can always be mapped to blocking synchronous calls when the underlying data connection is async
- Bad, because threads will be blocked because of I/O waits
- Bad, because of performance loss
Multi threaded access
Data clients can be concurrently accessed from multiple threads.
- Good, because maxiumum performance can be achieved when accessing async data clients
- Bad, because even strict single threaded data clients need to implement access synchronization
Async data client API
Data clients have an async API where data is returned with call back methods.
On initialization, a data client indicates whether it supports multithreaded calls. If a data client indicates single threaded operation only, the TEK must respect this and call the data client sequentially. See struct dataclient_capabilities
.
e.g.:
enum ASYNC_RESULT
{
ACCEPTED, // request was accepted and will be executed asynchronously
RETRY_LATER, // another request is in progress, can not execute this request
INVALID, // can not execute due to request errors
COMPLETED // request was completed synchronously
};
enum ASYNC_RESULT read(
DC dc,
TEK tek,
long request_id,
struct FIELD* items_to_read,
size_t number_of_items);
/// TEK callback from DC
void read_progress(
DC dc,
long request_id,
size_t current_count);
void read_result(
DC dc, long
request_id,
enum RESULT result,
struct FIELD_RESULT* result_data);
- Good, because async data clients can use async data access
- Good, because single threaded clients are explicitly allowed to block and call callback functions while function is running and thus map async call to a sync call without affecting async data clients