Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: How to speed up first logon ?



Permlink Replies: 7 - Last Post: May 15, 2017 3:54 PM Last Post By: Asger Joergensen
Asger Joergensen

Posts: 370
Registered: 11/18/08
How to speed up first logon ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 12, 2017 4:56 AM
Hi

I noticed that the first logon to the mail server takes 5 - 8 seconds.
So I maid a thread that does like this:

void __fastcall TAjIndyStarter::Execute()
{
   std::auto_ptr<TIdIMAP4> prt( new TIdIMAP4(0) );
   TIdIMAP4 *IdIMAP4 = prt.get();
   IdIMAP4->IOHandler = new TIdSSLIOHandlerSocketOpenSSL( IdIMAP4 );
 
   try{
 
      IdIMAP4->Host     = L"imap.one.com";
      IdIMAP4->Username = L"...";
      IdIMAP4->Password = L"...";
      IdIMAP4->Port     = 993;
      IdIMAP4->UseTLS   = utUseImplicitTLS;
 
      IdIMAP4->ReadTimeout = 10000;
 
      IdIMAP4->Connect( true );
 
   }catch(...){}
 
   IdIMAP4->Disconnect();
}


So I was wondering: is there a more simple way of initiating Indy ?

Thanks in advance
Best regards
Asger
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to speed up first logon ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 12, 2017 11:52 AM   in response to: Asger Joergensen in response to: Asger Joergensen
Asger Joergensen wrote:
I noticed that the first logon to the mail server takes 5 - 8 seconds.

That is likely not an Indy issue, but have you tried debugging TIdIMAP4 first to see where the extra time is being taken up? You might need to talk to your IMAP provider and have them trace the connection to see if anything weird is happening on their end.

So I maid a thread that does like this:

Just FYI, you don't need to call Disconnect() explicitly in that example, since the TIdIMAP4 destructor will close the socket for you, and the auto_ptr will call the destructor. You try/catch is also unnecessary, since TThread will terminate automatically if Execute() throws an uncaught exception.

void __fastcall TAjIndyStarter::Execute()
{
    std::auto_ptr<TIdIMAP4> IdIMAP4( new TIdIMAP4(0) );
    IdIMAP4->IOHandler = new TIdSSLIOHandlerSocketOpenSSL( IdIMAP4.get() );
 
    IdIMAP4->Host     = L"imap.one.com";
    IdIMAP4->Username = L"...";
    IdIMAP4->Password = L"...";
    IdIMAP4->Port     = 993;
    IdIMAP4->UseTLS   = utUseImplicitTLS;
 
    IdIMAP4->ReadTimeout = 10000;
 
    IdIMAP4->Connect( true );
}


So I was wondering: is there a more simple way of initiating Indy ?

Not without first knowing where the slowdown is actually occurring.

--
Remy Lebeau (TeamB)
Asger Joergensen

Posts: 370
Registered: 11/18/08
Re: How to speed up first logon ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 12, 2017 7:11 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy

Remy Lebeau (TeamB) wrote:

Asger Joergensen wrote:
I noticed that the first logon to the mail server takes 5 - 8 seconds.

Now that I timed it, it is more like 2 - 5 seconds, but when the connection have
been run once it is all together about 650 millisec. Which is fine.

If I close the app and run it again, the big delay is back.
With the big delay, the status looks like this:

IdIMAP4->Connect( true );
5 TIdSSLIOHandlerSocketOpenSSL Resolving hostname imap.one.com.
9 TIdSSLIOHandlerSocketOpenSSL Connecting to 46.30.211.88.
3701 TIdIMAP4 Connected.
342 TFormMailAccount fetching mailboxes
35 TIdIMAP4 Disconnecting.
4 TIdIMAP4 Disconnected.

The first row is milliseconds since last status.

To me it looks like it is the handshake, that take some time, but I don't
understand how, indy can remember anything from a handshake that is run in a
thread where everything is created on the fly and deleted again.

Just FYI, you don't need to call Disconnect() explicitly in that example,
since the TIdIMAP4 destructor will close the socket for you, and the auto_ptr
will call the destructor.

Yes I know, I just like to see it done. :-)

You try/catch is also unnecessary, since TThread will terminate automatically
if Execute() throws an uncaught exception.

But will it be quiet also ?
I did the try catch, so that no messages would pop up from the thread that
essentially does nothing concerning the user.

Thank you very much for helping
Best regards
Asger
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to speed up first logon ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 15, 2017 12:19 PM   in response to: Asger Joergensen in response to: Asger Joergensen
Asger wrote:

To me it looks like it is the handshake, that take some time

Possibly, but only in the case of implicit SSL/TLS, where the handshake is
performed as soon as the socket is connected. The hsConnecting status gets
issued before the handshake, and the hsConnected status gets issued after
the handshake is complete (and only if it is successful). I'm thinking about
adding some new statuses in between, to report when a handshake is being
performed.

but I don't understand how, indy can remember anything from a handshake
that is run in a thread where everything is created on the fly and deleted
again.

It doesn't.

You try/catch is also unnecessary, since TThread will terminate
automatically if Execute() throws an uncaught exception.
But will it be quiet also ?

Yes. The exception will be caught internally by TThread and assigned to
its FatalException property.

I did the try catch, so that no messages would pop up from the
thread that essentially does nothing concerning the user.

Worker threads do not display popup messages on uncaught exceptions. The
only reason the main UI thread does is because various message handlers inside
the VCL have their own local try/except blocks to perform such a display.

--
Remy Lebeau (TeamB)
Asger Joergensen

Posts: 370
Registered: 11/18/08
Re: How to speed up first logon ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 15, 2017 2:24 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy

Remy Lebeau (TeamB) wrote:

Asger wrote:

To me it looks like it is the handshake, that take some time

Possibly, but only in the case of implicit SSL/TLS, where the handshake is
performed as soon as the socket is connected. The hsConnecting status gets
issued before the handshake, and the hsConnected status gets issued after
the handshake is complete (and only if it is successful). I'm thinking about
adding some new statuses in between, to report when a handshake is being
performed.

It doesn't really matter if it is implicit or explicit. These below are run
using port 143 and utUseExplicitTLS, the first one using my starter thread
and the second one not using it and the difference in connection time is clear.
0 SSL Resolving hostname imap.one.com.
2 SSL Connecting to 46.30.211.88.
8 TIdIMAP4 Connected.
410 TFormMailAccount fetching mailboxes
117 TIdIMAP4 Disconnecting.
4 TIdIMAP4 Disconnected.

5 SSL Resolving hostname imap.one.com.
10 SSL Connecting to 46.30.211.88.
3485 TIdIMAP4 Connected.
403 TFormMailAccount fetching mailboxes
36 TIdIMAP4 Disconnecting.
3 TIdIMAP4 Disconnected.

But will it be quiet also ?

Yes. The exception will be caught internally by TThread and assigned to
its FatalException property.

Thanks for explaining
Best regards
Asger
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: How to speed up first logon ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 15, 2017 3:44 PM   in response to: Asger Joergensen in response to: Asger Joergensen
Asger wrote:

It doesn't really matter if it is implicit or explicit.

For purposes of your status messages, it does. In explicit mode, the hsConnected
status will be reported as soon as the socket is connected, before the handshake
is performed. In implicit mode, hsConnected is not reported until after
the handshake is finished.

These below are run using port 143 and utUseExplicitTLS, the first
one using my starter thread and the second one not using it and
the difference in connection time is clear.

But that doesn't tell you WHERE the time is actually being spent inside of
Indy. A lot of different things happen inside of Connect(), especially if
OpenSSL in involved.

Since you are using completely separate TIdIMAP4 and TIdSSLIOHandlerSocketOpenSSL
objects for each connection to the IMAP server, it can't be about shared
information being persisted between connections.

I'm guessing the real bulk of the time is actually being spent in loading
the OpenSSL DLLs into memory and initializing them when Connect() is called
for the first time. So, your starter thread ends up pre-loading OpenSSL,
which is then ready to go the next time your app needs to connect to the
server.

As such, instead of having the starter thread actually connect to a server,
just have it pre-load OpenSSL by itself, eg:

#include <IdSSLOpenSSL.hpp>
 
void __fastcall TAjIndyStarter::Execute()
{
    try
    {
        LoadOpenSSLLibrary();
    }
    catch(...)
    {
        // error loading OpenSSL, do something...
    }
}


--
Remy Lebeau (TeamB)
Asger Joergensen

Posts: 370
Registered: 11/18/08
Re: How to speed up first logon ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 15, 2017 3:54 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy

You were absolutely right !

LoadOpenSSLLibrary();

Works just as well.

Thanks
Best regards
Asger
Asger Joergensen

Posts: 370
Registered: 11/18/08
Re: How to speed up first logon ?
Click to report abuse...   Click to reply to this thread Reply
  Posted: May 13, 2017 6:04 AM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Hi Remy

I have done some more testing using gmail, but still using imap.one.com
in the stater thread:

Without the starter thread running:
IdIMAP4->Connect( true );
5 TIdSSLIOHandlerSocketOpenSSL Resolving hostname imap.gmail.com.
41 TIdSSLIOHandlerSocketOpenSSL Connecting to 108.177.15.108.
3563 TIdIMAP4 Connected.
441 TFormMailAccount fetching mailboxes
294 TIdIMAP4 Disconnecting.
3 TIdIMAP4 Disconnected.

With the starter thread running:
IdIMAP4->Connect( true );
1 TIdSSLIOHandlerSocketOpenSSL Resolving hostname imap.gmail.com.
1 TIdSSLIOHandlerSocketOpenSSL Connecting to 74.125.133.109.
82 TIdIMAP4 Connected.
855 TFormMailAccount fetching mailboxes
321 TIdIMAP4 Disconnecting.
3 TIdIMAP4 Disconnected.

Run a second time, without restarting the program.
IdIMAP4->Connect( true );
0 TIdSSLIOHandlerSocketOpenSSL Resolving hostname imap.gmail.com.
2 TIdSSLIOHandlerSocketOpenSSL Connecting to 74.125.133.109.
82 TIdIMAP4 Connected.
455 TFormMailAccount fetching mailboxes
290 TIdIMAP4 Disconnecting.
3 TIdIMAP4 Disconnected.

To me this indicate that most of the long delay is happening on my
PC otherwise it wouldn't help to logon to a different server.
P.s. I have a 50Mb fiber.

Best regards
Asger
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02