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.
Related
Hello #all on StackOverflow,
i am currently developing a Server Client application which communicates over HTTPS and does some Task which have to run in a seperate thread on the Server aswell as on the Client.
I am not really concert about thread efficiency on the Client side.
The normal Server Task Looks like this:
HTTPS Server recieves Login equest.
Opens up one longpolling thread for communication.
Server recieves instructions to open
Server opens a Client socket and a thread to read from it.
Server recieves message to Close socket.
Clientsocket thread should wait now.
-Besides: The longpolling thread should wait() as long as it has not recieved any data from the socketthread.
So in most cases one user can ahve multiple sockets on the serverside so one session consists of:
LongpollingThread<1---1>USER<1---0..5>Socket
My question now is what is the best practise to get some decend scalability?
Is it better to write permanent Thread which has a while loop inside.
Or is it better to write Tasks which run on a Threadpool and die after one I/O cycle.
CanĀ“t find a good answer online.
Maybe it is to specific..
Thanks in advance
Bladerox
I think you should use some kind of servlet engine or application server. Lots of your problems will be solved in there. Eg using async servlet processing will help you in your server component.
At client site: did you have a look at the multicast things in java.nio?
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 am looking to build an instant messenger in Java.
Clients will connect to the server to log in.
They will start a conversation with one or more other clients.
They will then post messages to the server that will relay the messages to all the clients.
The client needs to be continually updated when users post messages or log in.
so the way I see it, the client needs to run a server itself in a separate thread so that the main server can send stuff to it. Otherwise the client will have to the poll the main server every xyz seconds to get the latest updates. And that would need a separate thread anayway, as that would be purely for getting updates whereas the 'main' thread would be used for when the client initiates actions such as posting messages/inviting others to conversations etc...
So anyone recommendations on how to write this instant messenger? Does it sound like a good idea to make the connection a 'two-way' connection where both the client and server act as servers? Or is polling a better option? Anyone know how the IRC protocol does this?
There's no real advantage of having 2 connections unless they can be handled independently (for example receiving / sending a file usually done in a separate connection). A connection itself is already a two-way communication channel so it can be used to both send and receive messages, events etc. You don't need to poll server since client is able to maintain persistent connection and just wait for data to appear (optionally sending periodic PING-like message to ensure connection is alive).
IRC uses a single connection to server to exchange text commands. For example one of the main commands:
PRIVMSG <msgtarget> <message>
This command can be originated either by client or by server. Client sends PRIVMSG to notify that it wants to deliver message to one or more destination (in IRC this either user(s) or channel(s)). Server's task here is to properly broadcast this message to appropriate clients.
If you're using raw InputOutput streams then yes this is a good way of doing it. You create one thread on the clientside that acts in a similar fashion as the server thread - waits for any incoming updates and when it does it updates the client. I wouldn't call it a server though. So you'd ideally have 2 TCP/UDP connections one for requests made by the client and one to notify the client of server changes.
This solution in an enterprise environment would probably be done through some kind of messaging framework such as Spring Integration but dig deep enough and it will essentially be a similar way to how you mentioned.
Do you need a fully custom protocol or would it be sufficient to use the XMPP? There are several open source libraries implementing XMPP.
http://xmpp.org/xmpp-software/libraries/
e.g. http://www.igniterealtime.org/projects/smack/
For me, to develop instant messaging service, I will use websocket protocol instead of normal java socket because the normal socket can not work well with HTTP protocol and moreover some network providers and firewalls banned custom ports. If you develop it in normal socket, your service could not be accessed by web clients.
Did you plan to develop the instant messaging service yourself? How about using other protocols such as Jabber?
Assume a distributed communication system where client and server communicate via a stateless channel.
The client sends requests to the server and the server does processing and keeps internal records for each client.
Server sends back notifications to the clients as various events happen to the system, as needed.
The notification mechanism depends on the internal records.
My question is, what is the standard appoach in distributed computing to handle the client failures?
I.e. in this context, assume that the client process crashes or simply restarts.
The server still has the records for the client but now client and server are of sync.
As a result client will get notifications according to records created before restart. This is undesirable.
What is a standardized way to detect the client failures? E.g. client has restarted and previous records must be erased?
I thought of periodic callbacks to clients and if a client is not reachable, erase its records but I am not sure if this is a good idea. [EDIT] I thought of callbacks because, the period events send back to the client can be in very large intervals and so the client failure would not be noticable soon
Can anyone help on this? The context of my application domain is web services.
Thank you!
The standard approach varies from system to system depending to the architecture and domain. How the server finds out that the client is down? I think you don't need callbacks, since you send the notifications and can detect that the client is unreachable. For example:
send a notification to the client;
if success, goto 1;
else erase all the notifications in the queue for the client, set a flag to not collect events for the client.
When a client is connected:
unset the flag;
start sending notifications
Or even a simpler approach:
erase the notification queue for the client when it connects before initializing the conversation;
run a low-priority thread to erase all the notifications for all the clients which are older then X, to clean notifications for the client which will never come back.
Update after the original author comments
It strongly depends on how things are organized in your system. Assuming:
The server starts a thread (let's call it "agent") to serve a client, a thread per client.
The agent exits when the clients shuts down the session properly or goes down.
there is a private (which is not shared among agents/clients) record set for each client
there is a shared list of current clients which is used by another component (not an ordinary agent, let's call it "dispatcher") to distribute records for clients.
solution:
1. the server starts an agent and registers the client just connected to list of clients. The dispatcher gets notified that a new client arrived.
2. the agent consumes the records until client is connected. On client's shutdown and/or failure the agents unregisters the client and cleans the record set.
If things in your system aren't organized in the way described above, please provide some details.
Can a J2ME app be triggered by a message from a remote web server. I want to perform a task at the client mobile phone as soon as the J2ME app running on it receives this message.
I have read of HTTP connection, however what I understand about it is a client based protocol and the server will only reply to client requests.
Any idea if there is any protocol where the server can send a command to the client without client initiating any request?. How about Socket/Stream based(TCP) or UDP interfaces?.
If the mobile device doesnt allow you to make TCP connections, and you are limited to HTTP requests, then you're looking at implementing "long polling".
One POST a http request and the web-server will wait as long time as possible (before things time out) to answer. If something arrives while the connection is idling it can receive it directly, if something arrives between long-polling requests it is queued until a request comes in.
If you can make TCP connections, then just set up a connection and let it stay idle. I have icq and irc applications that essentially just sit there waiting for the server to send it something.
You should see PushRegistry feature where you can send out an SMS to a specific number have the application started when the phone receives that SMS and then make the required HTTP connection or whatever. However, the downside of it is that you might have to sign the application to have it working on devices and you also need an SMS aggregator like SMSLib or Kannel
You can open socket connection and implement "Hide" (or "Minimize") functionality in your app. Call this to hide:
Display.getDisplay(MyMIDlet.instance).setCurrent(null);
Listen to the server in a loop, and if you receive some message, popup the applicaion by calling this from canvas:
Display.getDisplay(MyMIDlet.instance).setCurrent(this);
But it dosen't work on all devices.
Socket push are supported by j2me. But it could work only if your server could deliver data to your mobile phone. Most likely that operator gateway don't allow to do this.
Maybe it would be possible if your mobile has static external IP address - some operators could provide this for $$.