Newsgroups : Borland : borland.public.delphi.internet.winsock : 2006 May : Re: Advanced Blocking Client (Newbie)

www.cryer.info
Managed Newsgroup Archive

Re: Advanced Blocking Client (Newbie)

Subject:Re: Advanced Blocking Client (Newbie)
Posted by:"Larry" (lchiass..@autoeurope.com)
Date:Fri, 19 May 2006 14:39:07

Gambit,

Thanks for taking the time and effort to respond.

> There are only 2 critical section "leaks" in Indy, and they are
> intentional
> during application shutdown.  Comments in the code explain why.  Also,
> this
> topic has been discussed many times before, so you can view them in the
> newsgroup archives at http://www.deja.com.

After each request is fullfilled, allocated critical sections are not
destroyed, sometimes, not all the time.
Also, the number of orphaned critical sections would vary (3, 4, 7, etc.).
I cannot think of any reason why, so this is why I made an assumption
we were doing things wrong in regards to Indy usage.

> As for the locks not being released at runtime, I highly doubt that.
> Critical section locks are always being released properly, via
> try..finally
> blocks.

When I say released I'm refering to the memory allocation, ie
create/destroy.


> That is not very helpful.  A socket connection can fail for a number of
> reasons.  You need to be more specific.  When Connect() fails, it will
> throw
> an exception, explaining why it failed.  What EXACTLY are you seeing
> happen?

I'll examine the exception raised for more information.
Also, if the .Connect method call fails, how should be handled?
Our current method of handling is to completely start over
(release the allocated resources and call the function again)
Or is it safe to just make the call again?
Perhaps, the correct answer is it depends upon what the exception is.

> There is no way to answer that since you have not explained what you are
> actually doing with them in the first place.

I thought I made that clear, but not.  Here are some code snipets that may
clearify:
{{ start }}
var
...
  tempTCP      : TIdTCPClient;
  tempHandler  : TIdSSLIOHandlerSocket;
begin
try
try

  tempHandler := nil;
  tempTCP     := nil;
...
      tempHandler := TIdSSLIOHandlerSocket.Create(nil);
      tempHandler.SSLOptions.Method := sslvTLSv1;
      tempHandler.SSLOptions.Mode := sslmClient;

....
      tempTCP := TIdTCPClient.Create(nil);
      tempTCP.Port := 443;
      tempTCP.Host := 'our_vendors_web_services.com';
      tempTCP.IOHandler := tempHandler;
      tempTCP.ReadTimeout := aintTimeOut;
.....
    try
      tempTCP.Connect (1500);
      except on e: exception do
      begin
        blnErrorSendCmd := TRUE;
        mCarrier.Session.errorStr := 'tempTCP.Connect ' + e.Message;
        raise Exception.Create(mCarrier.Session.errorStr);
      end;
    end;
....
    try
      dtmStart := Now;
      tempTCP.SendCmd(Command);
      dtmEnd := Now;
    except on e: exception do
      begin
        blnErrorSendCmd := TRUE;
        dtmEnd := Now;
        mCarrier.Session.errorStr := 'SendCmd Call Error: ' + e.Message;
        raise Exception.Create(mCarrier.Session.errorStr);
      end;
    end;
....
  except on e: exception do
    begin
      mCarrier.Session.errorStr := 'ThreadDoConnect_Exception ' + e.Message;
      raise Exception.Create(mCarrier.Session.errorStr);
    end;
  end;

finally
    //------------------------------
    // Release resources for socket.
    //------------------------------
    tempTCP.DisconnectSocket;
    FreeAndNil (tempTCP);
    FreeAndNil (tempHandler);
end;
end;

{{ end}}

> It is perfectly fine to create a socket in the main thread and then use it
> in a worker thread.  Blocking sockets work very well in that regard, as
> they
> are not bound to any particular thread.  Multi-threaded Indy servers
> create
> inbound sockets in a listening thread and then pass it to a worker thread
> for processing.  Multi-threaded Indy clients that process incoming data
> asynchronously pass their socket handle to an internal reading thread for
> processing.

Interesting.  So it sounds as though this is the recommended method.
Since we currently the socket resources in the thread, I wonder
if creating in the main thread would solve the orphaned CS mystery.
I'll give a go.


"Remy Lebeau (TeamB)" <no.spam@no.spam.com> wrote in message
news:446e03fc$1@newsgroups.borland.com...
>
> "Larry" <lchiasson@autoeurope.com> wrote in message
> news:446dd8ad$1@newsgroups.borland.com...
>
>> However, when profiling for leaks, there are times when Critical
>> Sections are not being released, and thus leading to a leak.
>
> There are only 2 critical section "leaks" in Indy, and they are
> intentional
> during application shutdown.  Comments in the code explain why.  Also,
> this
> topic has been discussed many times before, so you can view them in the
> newsgroup archives at http://www.deja.com.
>
> As for the locks not being released at runtime, I highly doubt that.
> Critical section locks are always being released properly, via
> try..finally
> blocks.
>
>> Also, there are times when a thread will try to obtain a socket
>> connection (.Connect method) only to have it fail.
>
> That is not very helpful.  A socket connection can fail for a number of
> reasons.  You need to be more specific.  When Connect() fails, it will
> throw
> an exception, explaining why it failed.  What EXACTLY are you seeing
> happen?
>
>> From what I've read on Indy, I believe we are not doing things
>> correctly in terms of Indy component use.
>
> There is no way to answer that since you have not explained what you are
> actually doing with them in the first place.
>
>> A thread will create and release any resources it needs in the context
>> of the thread, not the main thread (ie. .Create and .Destroy). For
> example,
>> a thread will create a db connection in the .Execute method of the
>> thread.
>> This includes socket creation and destruction
>
> It is perfectly fine to create a socket in the main thread and then use it
> in a worker thread.  Blocking sockets work very well in that regard, as
> they
> are not bound to any particular thread.  Multi-threaded Indy servers
> create
> inbound sockets in a listening thread and then pass it to a worker thread
> for processing.  Multi-threaded Indy clients that process incoming data
> asynchronously pass their socket handle to an internal reading thread for
> processing.
>
>> a back plan is to go client/server with Indy, where each thread created
>> by an instance of our ISAPI dll would be a client accessing an Indy
>> Server
>> (IS), where IS will then access the www for the web services provided by
>> our vendor (making our IS a client of web services).
>
> You don't need any Indy servers for that.  Your ISAPI threads can access
> the
> vendor web services directly.
>
>
> Gambit

Replies:

In response to:

www.cryer.info
Managed Newsgroup Archive