Regarding my last mail ('SMTP component not ready' exception), I learnt that 
the problem doesn't occur if I put the whole 'case RqType of: .. end;' into a 
try..except and simply ignore the exception. 

But I'm not sure if this is the correct way to handle it. I fear to miss some 
real exceptions which I'm also suppressing this way, and I don't like much 
quiet exceptions for complex operations.

How do you all handle such a situation?

Michael

> -----Original Message-----
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED]
> Behalf Of Kochendoerfer, Michael
> Sent: Wednesday, January 17, 2007 3:29 PM
> To: ICS support mailing
> Subject: Re: [twsocket] Still problems while sending SMTP
> 
> 
> Arno,
> 
> now I implemented it all the way you suggested. I have a 
> message handler procedure, which decides whether a record 
> results in a mail or in a print job. It then calls either 
> smtpCli.Connect() or DoPrint() (own form method) accordingly.
> 
> When it is a mail job and it has been processed, the 
> OnSessionClosed posts the handler message again. When it's a 
> print job, the very last line of DoPrint() posts the handler message.
> 
> I'm starting the whole processing by an initial PostMessage() 
> to this handler procedure and write useful info into a log 
> memo and a file. And as you wrote earlier, there's another 
> RequestDone (smtpQuit) after a OnSessionClosed call. But even 
> if I don't have any direct calls to the message pump, my own 
> handler message is processed before the smtpQuit state occurs 
> in OnRequestDone, so the smtpCli.Connect() may take place 
> _before_ OnRequestDone has finished processing the previous 
> mail. This sometimes results in a SMTP component not ready exception.
> 
> How can I prevent this situation from occuring? AFAIR, I 
> shouldn't have a loop somewhere testing for the component 
> state, so I need another mechanism to prevent it.
> 
> All other things are fine now, thanks a lot ;)
> 
> Michael
> 
> 
> > -----Original Message-----
> > From: [EMAIL PROTECTED] 
> > [mailto:[EMAIL PROTECTED]
> > Behalf Of Arno Garrels
> > Sent: Wednesday, January 17, 2007 10:55 AM
> > To: ICS support mailing
> > Subject: Re: [twsocket] Still problems while sending SMTP
> > 
> > 
> > Kochendoerfer, Michael wrote:
> > > Arno,
> > > 
> > > I think you addressed the problem correctly ;)  All subsequent
> > > Connect() calls (except the first one) are located within the
> > > OnRequestDone event procedure, in case of 
> RqType=smtpQuit. I now see
> > > this must be wrong.   
> > > 
> > > For a safe reconnect, should the message below be posted from
> > > OnRequestDone or from OnSessionClose? I guess it's the 
> > latter because
> > > it would be triggered after RqType=smtpQuit, right? Does calling
> > > Abort() also call OnSessionClose?   
> > 
> > SessionClose is the right place to post the message and yes 
> Abort also
> > triggers OnSessionClose. OnSessionClose fires when the connection is
> > closed no matter who closed it, and that may occur at *ANY TIME*. 
> > Note that if a request is still pending OnRequestDone will be
> > triggered afterwards as well. Calling Abort while the component is
> > still waiting for a response or while it's sending data will cause
> > OnRequestDone being triggered with an error code > 0, this was 
> > AFAIR (10053) Software caused connection abort.
> > 
> > ---
> > Arno Garrels [TeamICS]
> > http://www.overbyte.be/eng/overbyte/teamics.html
> > 
> >  
> > > Michael
> > > 
> > >> -----Original Message-----
> > >> From: [EMAIL PROTECTED]
> > >> [mailto:[EMAIL PROTECTED]
> > >> Behalf Of Arno Garrels
> > >> Sent: Wednesday, January 17, 2007 9:24 AM
> > >> To: ICS support mailing
> > >> Subject: Re: [twsocket] Still problems while sending SMTP
> > >> 
> > >> 
> > >> In order to reconnect safely you need to get out of your loop
> > >> after the session has been closed AND after OnRequestDone
> > >> has been triggered RqType smtpQuit as well. You must assign event
> > >> OnSessionClose to always get notified about connection close,
> > >> this can happen before as well as after OnRequestDone triggered
> > >> RqType smtpQuit, I'm not sure if you do something like that.
> > >> 
> > >> In order to get out of your loop just post a custom message,
> > >> something like:
> > >> 
> > >> PostMessage(Form1.Handle, WM_MAILSENT, Integer(Something),
> > >> Integer(Something));
> > >> 
> > >> The message handler is declared like:
> > >> 
> > >> const
> > >>   WM_MAILSENT = WM_USER + 1;
> > >> ..
> > >> protected
> > >>   procedure WmMailSent(var Msg: TMessage); message WM_MAILSENT;
> > >> ..
> > >> 
> > >> procedure TForm1.WmMailSent(var Msg: TMessage);
> > >> begin
> > >>   Display(IntToStr(Msg.WParam) + ' ' + IntToStr(Msg.LParam);
> > >>   ..
> > >>   In the message handler you can connect safely again.
> > >>   SmtpCli.Connect;
> > >> end;
> > >> 
> > >> 
> > >> ---
> > >> Arno Garrels [TeamICS]
> > >> http://www.overbyte.be/eng/overbyte/teamics.html
> > >> 
> > >> 
> > >> 
> > >> Michael Kochendoerfer wrote:
> > >>> Arno and all,
> > >>> 
> > >>> I realized and appreciated your hint to perform it all 
> > event-driven
> > >>> and I tried to accomplish it the way you suggested. 
> > However, I have
> > >>> some problems building the correct logic, it seems. In 
> > short words,
> > >>> the mail sending part of my application is as follows:
> > >>> 
> > >>> 1. Opening a SQL server query
> > >>> 2. Fill the standard properties (like Host, Port etc.) which are
> > >>> common between calls
> > >>> 3. Invoking my OnGetNextMailParam notify procedure 
> > *directly*, as if
> > >>> it had been called from the OnRequestDone handler
> > >>> 3a. OnGetNextMailParam checks if the query has still 
> records, read
> > >>> some fields, sets HdrTo if the record contains an mail address,
> > >>> calls Connect() and Next() for the query
> > >>> 3b. OnGetNextMailParam calls a message handler procedure 
> > if there's
> > >>> no target mail address, which invokes 3 again.
> > >>> 4. OnRequestDone is built like the sample code in MailSnd1.pas,
> > >>> except for the smtpQuit part. In my handler, 
> OnGetNextMailParam is
> > >>> called again, and if it reports a valid target address, it calls
> > >>> Connect() again (if not, it should have been handled by 3b)
> > >>> 
> > >>> This all should work from the beginning of the query to the end,
> > >>> where each record containing a target address should invoke the
> > >>> sending process and each other record should not 
> (records without
> > >>> an mail address are handled otherwise). But it doesn't 
> - it calls
> > >>> Connect() for two records and then it leaves.
> > >>> 
> > >>> I don't like you all to analyze my procedures but I'm 
> looking for
> > >>> some basic framework which would do it. I first thought 
> > of building
> > >>> the whole procedd into the smtpConnect part of 
> OnRequestDone, but
> > >>> this isn't possible due to the lack of mail addresses in 
> > some of the
> > >>> records. I'm really stuck here and I now realize my 
> concept won't
> > >>> work as needed.
> > >>> 
> > >>> The whole thing is not more or less than walking 
> through a record
> > >>> set and sending a mail to each receiver within that record set
> > >>> having a mail address. Other records having no mail address are
> > >>> handled otherwise, must be processed within the same loop 
> > but don't
> > >>> invoke any mail sending process. And - of course - it should be
> > >>> async ;) 
> > >>> 
> > >>> TIA,
> > >>> Michael
> > >>> 
> > >>> 
> > >>> Arno Garrels schrieb:
> > >>> 
> > >>>>> while not FlagDone do begin
> > >>>>>  //Application.ProcessMessages;  // Don't know 
> whether or not to
> > >>>>> use the message pump here   Sleep(50);
> > >>>>> end;
> > >>>>> 
> > >>>>> 
> > >>>> 
> > >>>> This is bad design. Do not wait in a loop. While sleeping the
> > >>>> calling thread is blocked. Instead let your derived 
> component do
> > >>>> the work in the background. In order to get notified 
> when the job
> > >>>> has finished add a custom event that fires when the 
> work is done,
> > >>>> or may be add another custom event that notifies the 
> application
> > >>>> when a single message has been sent/failed. In other words,
> > >>>> control the application completely thru events while 
> > executing the
> > >>>> mailing. So in the ButtonClick handler there the call to 
> > start the
> > >>>> mailing should be the very last line.
> > >>>> 
> > >>>> ---
> > >>>> Arno Garrels [TeamICS]
> > >>>> http://www.overbyte.be/eng/overbyte/teamics.html
> > >>>> 
> > >>>> 
> > >>>> Kochendoerfer, Michael wrote:
> > >>>> 
> > >>>> 
> > >>>>> You all are giving excellent information in this mailing list,
> > >>>>> thanks a lot!
> > >>>>> 
> > >>>>> I guess my problem is - as you describe - that the 
> component is
> > >>>>> still active, even if smtpQuit has been reached within
> > >>>>> OnRequestDone. I don't currently check if it's still 
> connected,
> > >>>>> but I will change it. Errors will be checked and 
> force to abort
> > >>>>> the entire mail and write some log entries.
> > >>>>> 
> > >>>>> As Arno said earlier, I'd like to have async components 
> > because of
> > >>>>> their benefits. But in fact, for me it is a sync 
> call, at least
> > >>>>> for each single mail. IOW, I've to wait until each particular
> > >>>>> mail has been finished before I'm advancing to the 
> next one. So
> > >>>>> I'm starting with Connect(), let the OnRequestDone do the
> > >>>>> background stuff and set a flag if either aborted or 
> quit. Now I
> > >>>>> know I've to wait also for not Connected. But what's 
> the correct
> > >>>>> method to wait for completion? Currently, I have a loop after
> > >>>>> calling Connect() looking like this:
> > >>>>> 
> > >>>>> while not FlagDone do begin
> > >>>>>  //Application.ProcessMessages;  // Don't know 
> whether or not to
> > >>>>> use the message pump here   Sleep(50);
> > >>>>> end;
> > >>>>> 
> > >>>>> Any thoughts?
> > >>>>> 
> > >>>>> TIA,
> > >>>>> Michael
> > >>>>> 
> > >>>>> 
> > >>>>> 
> > >>>>> 
> > >>>>>> -----Original Message-----
> > >>>>>> From: [EMAIL PROTECTED]
> > >>>>>> [mailto:[EMAIL PROTECTED]
> > >>>>>> Behalf Of DZ-Jay
> > >>>>>> Sent: Tuesday, January 16, 2007 10:57 AM
> > >>>>>> To: ICS support mailing
> > >>>>>> Subject: Re: [twsocket] Still problems while sending SMTP
> > >>>>>> 
> > >>>>>> 
> > >>>>>> 
> > >>>>>> On Jan 16, 2007, at 02:49, Arno Garrels wrote:
> > >>>>>> 
> > >>>>>> 
> > >>>>>> 
> > >>>>>>> When the response to the Quit command is received the 
> > connection
> > >>>>>>> (may) still be alive. So watch both, whether Quit 
> response has
> > >>>>>>> been received as well as the SessionClose event. 
> Call connect
> > >>>>>>> only after the session has been closed.
> > >>>>>>> Don't start a loop directly from an event handler but post a
> > >>>>>>> custom message to some Window, in it's message 
> > handler start the
> > >>>>>>> next loop.
> > >>>>>>> 
> > >>>>>>> 
> > >>>>>> You could, in fact, re-use the connection if the next message
> > >>>>>> is to be
> > >>>>>> sent through the same server.  All you have to do 
> is, after the
> > >>>>>> DATA command is completed and the server 
> acknowledges receipt,
> > >>>>>> check SmtpCli.Connected, if you are still connected 
> then reset
> > >>>>>> your state-machine to start the cycle fromthe MAIL 
> > FROM command.
> > >>>>>> Some servers required a "reset" (RSET) command be 
> sent to reset
> > >>>>>> state, and it doesn't hurt to send it anyway.  The important
> > >>>>>> thing is to check the
> > >>>>>> connection, because something may have happened -- 
> and indeed,
> > >>>>>> some servers have anti-spamming filters that will 
> kick you out
> > >>>>>> after receiving DATA that they determine is spam, and 
> > some won't
> > >>>>>> allow you to
> > >>>>>> re-send after one message.  So the algorithm would 
> be something
> > >>>>>> like:
> > >>>>>> 
> > >>>>>> 1. Connect
> > >>>>>> 2. HELO
> > >>>>>> 3. MAIL FROM
> > >>>>>> 4. RCPT TO
> > >>>>>> 5. DATA
> > >>>>>> 6. If connected:
> > >>>>>> 6.a (yes) RSET then back to 3
> > >>>>>> 7. QUIT
> > >>>>>> 8. back to 1
> > >>>>>> 
> > >>>>>> Of course, you should check for errors after each step (in
> > >>>>>> OnRequestDone, before changing states).  Keep in mind that
> > >>>>>> some errors
> > >>>>>> are recoverable (transient: 400+), some errors are not
> > >>>>>> (non-transient:
> > >>>>>> 500+), and some are somewhere in between (like RCPT warnings,
> > >>>>>> etc). Recoverable errors allow you to try again, or require a
> > >>>>>> RSET and start
> > >>>>>>> from step 3, while non-transient errors require closing the
> > >>>>>> connection
> > >>>>>> and starting from scratch.  If you are sending 
> general messages
> > >>>>>> to strange servers "in the wild" it gets pretty complicated,
> > >>>>>> specially when you factor in all the 
> non-RFC-compliant servers;
> > >>>>>> but if your application is of limited purpose, sending 
> > using the
> > >>>>>> same server all the time, the errors and issues that 
> may occur
> > >>>>>> are predictable and substantially less.
> > >>>>>> 
> > >>>>>> Building this logic in a simple state-machine using
> > >>>>>> OnRequestDone makes
> > >>>>>> it fairly easy to make your application powerful and 
> > efficient --
> > >>>>>> the reason we always push for the use of async methods.
> > >>>>>> 
> > >>>>>> dZ.
> > >>>>>> 
> > >>>>>> --
> > >>>>>> DZ-Jay [TeamICS]
> > >>>>>> http://www.overbyte.be/eng/overbyte/teamics.html
> > >>>>>> 
> > >>>>>> --
> > >>>>>> To unsubscribe or change your settings for TWSocket 
> > mailing list
> > >>>>>> please goto http://www.elists.org/mailman/listinfo/twsocket
> > >>>>>> Visit our website at http://www.overbyte.be
> > >> --
> > >> To unsubscribe or change your settings for TWSocket mailing list
> > >> please goto http://www.elists.org/mailman/listinfo/twsocket
> > >> Visit our website at http://www.overbyte.be
> > -- 
> > To unsubscribe or change your settings for TWSocket mailing list
> > please goto http://www.elists.org/mailman/listinfo/twsocket
> > Visit our website at http://www.overbyte.be
> > 
> -- 
> To unsubscribe or change your settings for TWSocket mailing list
> please goto http://www.elists.org/mailman/listinfo/twsocket
> Visit our website at http://www.overbyte.be
> 
-- 
To unsubscribe or change your settings for TWSocket mailing list
please goto http://www.elists.org/mailman/listinfo/twsocket
Visit our website at http://www.overbyte.be

Reply via email to