I have a form that is sending 4 separate emails when it is processed all of which contain up to 4 attached PDF/Word documents. The way I have it setup is that I have spoolenable="false" on every email so that they are sent immediately. Then, on the last email I also have remove="true" so that the attachments are deleted from my server. The problem that I'm having is that only 2 of the 4 emails are being sent before I get a:
java.net.SocketTimeoutException: Read timed out.
Not really sure what I can do to fix this but I'm willing to try any suggestions.
Thanks
This would be a poor use of spoolenable="false". What that setting does is set the email to send immediately bypassing the built in mail spooler. This makes the client request have to wait to return till the email is sent. This impacts the users of the system as they now have to wait for the CF server to actually send the email. This now adds a potential point of failure to the client request and could cause other issues.
If you want to avoid the spool I would do the mail send in a cfthread. This way you are at least not impacting the client with the mail send.
Related
-- EDIT: --
To rephrase the question.
Does HTTP know anything about the status of underlying TCP connection?
TCP is a reliable protocol. When the server sends data to the client it expects an acknowledgment signal from that client. What happens in HTTP when the underlying server side TCP connection fails to receive the ACK signal?
-- ORIGINAL Question: --
I am trying to solve a design issue on our HTTP client/server app.
Here is the situation:
The server runs on Tomcat, and we are somewhat limited to using Jersey or Servlets for the server side implementation.
The client requests data from the Server, which once read is deleted.
Data must not be deleted if the client has not received it.
There is no confirmation from the client if the data is received or not.
The client impl cannot be changed in any way.
The network connection is unstable and can be interrupted for long periods of time (e.g. 30 sec.) and also often.
The problem: if the client made a request and shortly after lost connection to the server, the server will not recognize this and it will delete and send the data to the client over the dead connection.
Ideally, we want to get an IOException when flushing the data stream to the client and handle it accordingly:
try (ServletOutputStream outputStream = httpServletResponse.getOutputStream()) {
outputStream.write(bytes);
outputStream.flush();
} catch (Exception e) {
// TODO: do something ...
}
I simulated this locally by killing the client shortly after sending the request or by setting a very low client read timeout value. In both cases I got a server side exception (with bioth Jersey and Servlets).
The last test was sending a request over a network and pulling the network cable in the process.
Unfortunately I did not get the expected result. The server streamed the data back without recognizing the interrupted connection.
So, does anyone have an idea how to force a Server side exception when the connection to the client is broken?
Any other ideas that don't involve using Sockets or confirmation calls from the client?
Thanks in advance!
Instead of deleting the file in real time, you can write a message on a queue in order to delete it later. The delete would have to check a database where you write if the client received the file completely.
I don't think there's a way to know for certain whether the data arrived to the client unless the client sends an acknowledgement message.
The only solution seems to be not actually deleting the data, but keeping it and setting a 'deleted' flag. But since I don't know the particular use case, I'm not sure if this helps...
TCP is a two way protocol.
If you set up an input stream and call InputStream.read(), this should return -1 if the client has disconnected.
More detail here:
Java Sockets: check if client is able to receive message from server
My client sends 12 requests(nothing could be wrong since they are very similiar) through loop to a Servlet on the server(Tomcat).
When I see the app server access log, I only see 8 of them. I am not sure if the client sent all requests to the server successfully.
Could someone verify that request isn't logged to access_log until the response is available. If this is the case, even all requests reached app server correctly, but four responses are not available.
Is there anyway to find out why do request get lost? Is there any time out issue on the server side? For example, if it takes too long to respond, it drops the request.
By the way, I am running both client and server on my local machine.
It can't be written until the response is sent, otherwise it can't know what the response code was, but it is also subject to buffering and flushing.
I'm experiencing a weird issue with my mail server. Currently i'm using Apache James as a relay to dispatch emails to an external mail server. Sometime it happens that even if I receive an SMTP code 250 from the external mail server, the email diasappears and never get delivered or it is delivered after a very long time. Point is: am i right assuming that until i receive the SMTP code 250 of successful delivery from the external server, it is not a problem of my mail server?
Even you get SMTP return code 250, it doesn't guarantee your email will arrive in final destination.
That return code means that the relay server ACCEPTS your email-delivery request. After they accept the request, who knows what happen after that. Several possibilities:
The remote server scan your email with AntiSpam daemon and (unfortunately) your email is mis-idenfified as spam. So they discard/drop it.
The remote server just don't like your email. Maybe your IP Address blacklisted. So they silently discard it.
The remote server is busy processing other jobs. So they delay your email delivery.
The server happily to forward your email to final destination right now.
Further info: Simple_Mail_Transfer_Protocol on Wikipedia
Scenario 1 :
Setup a JMS Queue in your server
Java code to send Messages to Producer
Create a JMS Producer, which when invoked, should receive the email data (subject, body, to , cc etc) and post it to the Queue setup in step 1
Create a JMS Consumer, which subscribes to the Queue created in Step 1, and its onMessage should call the JavaMail API to send the email.
Scenario 2 :
Directly call the JavaMail API to send the email.
I know about how to use and what JMS and Java Mail are doing.Thing is why we have to go from Scenario 2 to Scenario 1 for sending mails.Initially we did Scenario 2.Now we are using Scenario 1.From Different parts of the Big Application are sending mails so we use JMS Queue ,there will be Consumer of Queue from there sending mails.Please help me to understand.
You would use this mechanism in a large application for 2 reasons:
1) You don't want your clients to have to wait for the mail to be sent.
2) You don't want to lose mails if you lose connectivity to your mail server for any reason.
You would do this if you don't have a relyable MTA near your local machine but need to be sure your mail will be send. For example if there is a network outage but you rely on Java Mail to send your mail without additional logic, your mail will not be send at all.
Using JMS you can reschedule the mail for transfer as soon as the real MTA will become available again.
Besides:
the conversation with the mail provider (SMTP und POP3) is
asynchronous and close to the JMS/MDB api. So why should i use a
different API than JMS ?
You can keep the mail handling in one transaction, together with some database changes other activities. I remember too many Spring .. sic' projects, where the customer demmands for a atomic operation, that included a state change in a db ;-)
Image, the messages you send become more compulsory and you have to connect to a X400 service. Simply think of the slight code change (and the change of the RA) and you will discover to met the right architectual descision.
I use an external mail server to send SMTP mails, this server is effectively beyond my control.
A couple of times recently this mail server has had issues and it's caused my Java (Struts/Spring) app to completely hang when waiting for a reply from the mail server.
I'm using the Spring org.springframework.mail.javamail.JavaMailSender to send mails.
When the external mail server is having issues it's the following line that freezes mailEngine.send(mailMessage);
I don't mind that sometimes emails don't get sent but how can I stop this from freezing my application while it waits for a reply from the SMTP server?
Are there any good email queuing solutions for Java?
You can send the emails in a background thread.
Thread your calls to the SMTP server. You can make use of the ExecutorService (various implementations exist) and drop in Runnables to be executed at a later stage (out of band). The advantage of this approach is that you don't have to explicitly code your threading model.
If you collect the Future object from the Executor upon submission, you can call get() with a suitable timeout and cancel (and perhaps re-submit/retry) upon timeout.