Channel::read behavior
I am using the Elektron ETA SDK for Java, v. 3.1.1.L1. Having subscribed to a RIC, I have observed that, when notified by the Selector of an OP_READ operation, Channel::read returns null most of the time, with ReadArgs::readRetVal having a positive value. According to the documentation, this indicates that a full TransportBuffer is not available yet, but that there are more bytes to be read, so Channel::read should be called again. Doing so eventually yields a full TransportBuffer.
My concern relates to the frequency this occurs. As an example, for an incoming full TransportBuffer rate of 2K/sec, I receive around 250K/sec of responses returning null with a positive readRetVal, which I promptly ignore, since there is no processing that is needed for those.
Is this expected, and if so, is there way to suppress such responses, to save on unnecessary processing?
Best Answer
-
From my test, this scenario usually happens when the payload in the retrieved message is huge, such as the payload of data dictionary domain.
In the example code, ChannelSession::readInt(...) method has a do/while loop which calls the read method while the readArgs.readRetVal() is more than TransportReturnCodes.SUCCESS (0).
private int readInt(PingHandler pingHandler, ResponseCallback callbackclient, Error error)
{
TransportBuffer msgBuf;
do /* read until no more to read */
{
msgBuf = channel.read(readArgs, error);
...
}
while (readArgs.readRetVal() > TransportReturnCodes.SUCCESS);
...
}Channel.read() method not only reads the raw data from network but it also processes the raw data and returns the buffer.
When the returned buffer is null and readRetVal return a value which is more than zero, it indicates the more raw data needs to be read from the network in order to create the complete buffer.
The code is designed to do this as fast as possible. Therefore, it is possible that the read method method is called too fast without reading any raw data from the network. You can verify this by print readArgs.uncompressedBytesRead() and readArgs.readRetVal() when the returned buffer is null.
You can see that there are a lot of calls that uncompressedBytesRead returns zero.
### Read return null: uncompressedBytesRead: 0, readRetVal:3472
#### Read return null: uncompressedBytesRead: 0, readRetVal:3472
#### Read return null: uncompressedBytesRead: 0, readRetVal:3472
#### Read return null: uncompressedBytesRead: 0, readRetVal:3472
#### Read return null: uncompressedBytesRead: 6138, readRetVal:2142
#### Read return null: uncompressedBytesRead: 6130, readRetVal:152
#### Read return null: uncompressedBytesRead: 0, readRetVal:152
#### Read return null: uncompressedBytesRead: 0, readRetVal:152
#### Read return null: uncompressedBytesRead: 0, readRetVal:152
#### Read return null: uncompressedBytesRead: 0, readRetVal:152
#### Read return null: uncompressedBytesRead: 0, readRetVal:3624
#### Read return null: uncompressedBytesRead: 0, readRetVal:4292
#### Read return null: uncompressedBytesRead: 0, readRetVal:4292
#### Read return null: uncompressedBytesRead: 0, readRetVal:4292
#### Read return null: uncompressedBytesRead: 0, readRetVal:4292
#### Read return null: uncompressedBytesRead: 0, readRetVal:4292
#### Read return null: uncompressedBytesRead: 0, readRetVal:4292
#### Read return null: uncompressedBytesRead: 0, readRetVal:4292
#### Read return null: uncompressedBytesRead: 0, readRetVal:4292
#### Read return null: uncompressedBytesRead: 6138, readRetVal:2294From the code, this is expected because it is designed to get the buffer as fast as possible.
However, if you would like to avoid this, you can add a short sleep for this condition. This can reduce the number of channel read called.
if(msgBuf == null && readArgs.readRetVal() > TransportReturnCodes.SUCCESS){
try {
Thread.sleep(5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}#### Read return null: uncompressedBytesRead: 6138, readRetVal:2142
#### Read return null: uncompressedBytesRead: 6130, readRetVal:47072
#### Read return null: uncompressedBytesRead: 6138, readRetVal:40934
#### Read return null: uncompressedBytesRead: 6138, readRetVal:34796
#### Read return null: uncompressedBytesRead: 6138, readRetVal:28658
#### Read return null: uncompressedBytesRead: 6138, readRetVal:225200
Answers
-
Thank you for the detailed explanation, that makes sense.
0
Categories
- All Categories
- 6 AHS
- 39 Alpha
- 161 App Studio
- 4 Block Chain
- 4 Bot Platform
- 16 Connected Risk APIs
- 47 Data Fusion
- 30 Data Model Discovery
- 608 Datastream
- 1.3K DSS
- 577 Eikon COM
- 4.9K Eikon Data APIs
- 7 Electronic Trading
- Generic FIX
- 7 Local Bank Node API
- Trading API
- 2.7K Elektron
- 1.3K EMA
- 236 ETA
- 519 WebSocket API
- 33 FX Venues
- 10 FX Market Data
- 1 FX Post Trade
- 1 FX Trading - Matching
- 12 FX Trading – RFQ Maker
- 5 Intelligent Tagging
- 2 Legal One
- 20 Messenger Bot
- 2 Messenger Side by Side
- 9 ONESOURCE
- 7 Indirect Tax
- 59 Open Calais
- 264 Open PermID
- 39 Entity Search
- 2 Org ID
- PAM
- PAM - Logging
- 8.4K Private Comments
- 6 Product Insight
- Project Tracking
- ProView
- ProView Internal
- 20 RDMS
- 1.4K Refinitiv Data Platform
- 367 Refinitiv Data Platform Libraries
- 3 Refinitiv Due Diligence
- LSEG Due Diligence Portal API
- 3 Refinitiv Due Dilligence Centre
- Rose's Space
- 1.1K Screening
- 18 Qual-ID API
- 13 Screening Deployed
- 23 Screening Online
- 10 World-Check Customer Risk Screener
- 990 World-Check One
- 44 World-Check One Zero Footprint
- 45 Side by Side Integration API
- Test Space
- 3 Thomson One Smart
- 1.2K TR Internal
- Global Hackathon 2015
- 2 Specialists Who Code
- 10 TR Knowledge Graph
- 150 Transactions
- 142 REDI API
- 1.7K TREP APIs
- 4 CAT
- 21 DACS Station
- 117 Open DACS
- 1.1K RFA
- 103 UPA
- 172 TREP Infrastructure
- 224 TRKD
- 886 TRTH
- 5 Velocity Analytics
- 5 Wealth Management Web Services
- 60 Workspace SDK
- 9 Element Framework
- 5 Grid
- 13 World-Check Data File
- Yield Book Analytics
- 46 中文论坛