Easy to way to time Indy connect and receive times? - delphi

Is there an easy way to get the time it took Indy to connect, and the time it took to receive data, in a TIdHTTP.Get() or TIdHTTP.Put() operation?
EDIT:
I want to get statistics to determine which timeouts are best to use for the ReceiveTimeout and ConnectTimeOut properties.

For timing a connect, you can use the OnStatus(hsConnecting) and OnStatus(hsConnected)/OnConnected events. Note that if a URL involves a hostname (which is the usual case), there is also an OnStatus(hsResolving) event that precedes the OnStatus(hsConnecting) event. However, DNS resolution does not play into ConnectTimeout handling at this time.
For timing the receive, that is a bit trickier, since there are no events for detecting the end of sending a request, or the beginning/ending of reading a response 1. And also that a given HTTP request may involve multiple steps (redirects, authentication, etc), which may also involve multiple disconnects/re-connects since HTTP is a stateless protocol not dependent on a persistent connection, like most other protocols are. So, about the only way I can think of accomplishing this is to attach an Intercept component to the TIdHTTP.Intercept property and then manually parse the HTTP messages as they are being exchanged.
1 Actually, that is not entirely true. There is a TIdHTTP.OnHeadersAvailable event, which is fired after the HTTP response headers have been read, and before the HTTP response body is read, at least. So, if you don't care about the timing of the headers, you can use that event to start timing the receiving of the body data, at least. And then stop the timing when Get()/Post() exits. For each multi-step that requires TIdHTTP to repeat a request, you should get a new OnHeadersAvailable event, which you can use to reset your timer. That way, you end up with the time of the final response only.
However, note that ReceiveTimeout is a per-byte timeout, so an alternative might be to use a custom TStream (or Indy's TIdEventStream) to receive the HTTP response data into, and then you can time the durations between individual writes to that stream by overwriting its Write() method (or using the OnWrite event).

Related

CAN bus delay between sending remote requests

What is the proper way to send multiple remote requests in CAN2.0B/A? Is it usual to have some delay between them like 1/50s, for the receiver to react? I know it shouldnt be needed if proper interrupts are used, i just want to do it the way it is originally designede for.
For future people, no delay is usually needed, be aware an answer can be received while sending remote requests.

Delphi - indy send post using multiple IdHTTP in the same time

How can I send multiple post requests using TIdHTTP at the same time?
lHTTP1.Post('http://'+cURL+'/build.php?',lParamList, ResponseContent);
lHTTP2.Post('http://'+cURL+'/build.php?',lParamList, ResponseContent);
lHTTP3.Post('http://'+cURL+'/build.php?',lParamList, ResponseContent);
I tried using three threads to do that, but there is a one second delay between every post message.
How can I send all the post messages in the same second?
Since TIdHTTP is a blocking component, using separate threads is the correct approach. The 1s delay on each post could be related to how the OS schedules threads, or it might be related to network delays, or you might be using a version of Indy that has internal delays (for instance, if an HTTP server sends a 3xx response to a POST request, TIdHTTP waits up to 5s to make sure the server sends a proper response body - some buggy servers do not). It is difficult to know where your 1s delay is actually occurring. You will have to debug/profile your project to find out, we can't do that for you.

How to synchronize message status updates in Delphi Indy

RFC 3501 states in section 6.1.2. that you should use the NOOP command for polling.
Though in TIdIMAP4 there's only the KeepAlive method using it, which is implemented as a procedure, i.e. doesn't return anything.
So how to check for status updates like e.g. new messages or read status changes? I.e. how can I do manual polling with TIdIMAP4? Which methods and properties are involved in doing that? And how to get the (U)IDs these messages?
Or is it even possible to use the IDLE command specified in RFC 2177 to avoid polling and to get updates automatically?
IMAP is technically an asynchronous protocol, but TIdIMAP4 is currently implemented as a synchronous client. As such, unexpected/out-of-order data is either discarded, treated as untagged data, or treated as error data, depending on timing and context. Untagged/extra data is accessible from the TIdIMAP4.LastCmdResult property, which you can type-cast to TIdReplyIMAP4 to access its Extra sub-property.
IDLE is not currently supported in TIdIMAP4. There are tickets in Indy's issue trackers (see here and here) to add IDLE support in a future release, maybe in Indy 11. Until then, you will have to poll the mailbox envelopes periodically, keeping track of messages you have already seen so you can detect new messages.
Yes, you can use IDLE to avoid NOOP and in general it's a good idea.
However, that won't give you any results. In a way, IMAP commands don't have results. They tell the server what you want, and the server tells you things. The server is free to tell you things for other reasons as well, including the goodness of its heart.
You might say that NOOP means "hi server, now is a good time to tell me things, I'm listening" and IDLE means "hi server, I'm listening all the time, so just tell me whatever you want whenever you want". Both also mean "and btw, restart your inactivity timeout if you have one".
The server will send you EXISTS, FETCH and other responses, which I expect TIdIMAP4 forwards to you in some way. (Yes, they're called responses even though they're not in response to any command of yours. They may be sent in response to someone else having sent you mail, for instance. Stupid naming.)

Best pratice ro handle Indy TCP Server execute in Delphi Xe3

When receiving data from a indy TCPServers execute method i generally handle it by reading the data by doing the following:
AContext.Connection.IOHandler.ReadLn;
and then process the data in the execute method. Most of the data that comes through are small JSon strings.
In the future i will need to handle larger data chunks and was wondering what the best pratice is to do so?
Is it a good idea to add the incoming data to a TidContext class and process it using some worker thread? Any thoughts or code samples would be appreciated. I use Indy 10 and Delphi XE3
The OnExecute event is already triggered in a worker thread, so it doesn't matter how long it takes to receive the data. As long at the data only has 1 (CR)LF at the end of it, ReadLn() will not care how long the string actually is (subject to the IOHandler's MaxLineAction and MaxLineLength properties, which you can tweak if needed). However, if the data has more than 1 (CR)LF in it, then you will have to either:
transmit the string length before transmitting the actual string, then use ReadLongInt() and ReadString() instead of ReadLn() in the receiving code.
terminate the string with a different delimiter than (CR)LF at the end, and then pass that delimiter to ReadLn() so it knows when to stop reading.
If the server has to receive incoming requests at a guaranteed rate, without blocking the consumers by slow request processing, saving the big data chunks to a datastore (file, database) for later processing could be a solution.
This would make the HTTP server thread available for the next request as soon as possible.
It also allows to do the data processing by multiple worker servers, with load balancing.

How does LoadRunner recognize that data has been returned?

If I e.g. record an action that is querying database and the result is returned after 1 minute, how does Loadrunner recognize this? Because it appears in the communication between client and server?
Thanks
Loardrunner makes a HTTP request in a thread, and then that thread waits for it to return until the timeout period.
When the request returns with a response, LoadRunner parses it and based on your code, can extract any information from it. It can also easily measure the time it waited to get the response.

Resources