design issue with sending email notification while calling jersey service (PUT)
I am having a design issue here. I have a RESTful web service implemented with jersey. I am also using spring mail to send email.
My specification needs to notify a certain group of users (15-20 approx.) that a PUT request has been made and inform them with the modification of a resource. 开发者_运维问答Also I need to send a JSON array to the client who made the request as a response.
Right now what I have done is after the modification in my method where I process the PUT service,I send emails to the users and then I return the JSON status.
But why should the client wait for the mail notification to finish?What if my suer list is long and clients wait a long time to get a response. It is not his headache. But also I need to notify users too within the PUT method. If I return JSON I lost the context to send notification by getting out from the request response cycle.
Is there a better way to do that?
To have an idea,I am providing the relevant part of my code:
//first notify users
notifyUsers(event,jsonEntity,NotificationType.TicketType.UPDATED);
//then return response
return new JSONObject()
.put("response_code:", Response.status(Status.OK).build())
.put("title", evento.getDescrizioneevento())
.put("status", getEventAsString(evento.getStatoevento()))
.put("solved", evento.getCausascatenante());
Make "notifyUsers" asynchronous.
Queue up the request, and process it later. You can use a simple BlockingQueue in a singleton with a thread listening to the other end, or you can set up a more formal queuing system such as JMS. You could also insert the request in to a database and have something listening for activity there.
Or you could simply fire up a simple thread right there, and let it run as you return from the request. That can work too.
All sorts of alternatives with different pros and cons.
In the class where I have my web service I have this inner class which will executes in seperate thread.
class MailExecutorService implements Runnable {
EventiAnomali eventiAnomali;
JSONObject jsonEntity;
NotificationType.TicketType type;
public MailExecutorService(EventiAnomali eventiAnomali,JSONObject jsonEntity,
NotificationType.TicketType type) {
this.eventiAnomali = eventiAnomali;
this.jsonEntity =jsonEntity;
this.type = type;
}
public void run() {
notifyUsers(eventiAnomali,jsonEntity,type); // I've made notifyUser asynchronous
}
}
In the @PUT method just before the return I've used,
executorService.execute(
new MailExecutorService(evento,jsonEntity,
(evento.getStatoevento().equals("5"))? NotificationType.TicketType.CLOSED:
NotificationType.TicketType.UPDATED));
response = MY_JSON
I've put executor.shotDown()
in my finally
block. Then the last line is the retured JSON
(response)
Are all these okay to do? Not to mention it works ..
精彩评论