My grails app is sending emails asynchronously in one of its controllers. Asynchronously, because it should be sent after a lengthy process. I am currently using the executor plugin and the runAsync closure.
def sendEmails() {
...
runAsync {
// ... Some lengthy process before emailing
myMailService.send('someone#somecompany.net',
g.render(template: 'mail', model: resultOfLengthyProcess))
}
...
}
I am running it after the lengthy process, because the model in the render function call contains the result of that process.
I want to use the g.render() method because the email is a big gsp template with lots of pictures and content.
Now that g.render call will fail, because it is being called from another thread. It throws java.lang.IllegalStateException with the message:
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread? If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
How can I solve this issue? I am open to any answers/suggestions.
You need a request in order to use render directly, and with an asynchronous block you loose it.
However you should be able to achieve what you want by injecting the PageRender in your controller and calling it from the async block.
class MyController {
grails.gsp.PageRenderer groovyPageRenderer
def sendEmails() {
// ... Some lengthy process before emailing
myMailService.send(
'someone#somecompany.net',
groovyPageRenderer.render(template: 'mail', model: resultOfLengthyProcess)
)
}
}
I would suggest to use JMS (with the jms plugin), encapsulating the lengthy process in a service.
Related
We are building a custom way to process timesheets using eConnect. A method is exposed that allows out timesheets documents to be submitted to GP. This method is run synchronously, but can take a long time to complete. How can I handle this so that the user's client can make additional requests in the meantime?
I have attempted to use async/await on this method, but because the method isn't awaitable this will not work. The method depends on a windows service. I have researched potentially wrapping it in Task.Run but have hesitations since this sounds like a bad practice.
public bool SaveTimesheets(string ConnectionString, List<PATimeSheetsType> Timesheets)
{
string timesheetDocument = string.Empty;
//Creating timesheet document
bool result = false;
eConnectMethods eConnectMethods = new eConnectMethods();
//CreateEntity takes minutes to complete and return
result = eConnectMethods.CreateEntity(ConnectionString, timesheetDocument);
return result;
}
The behavior I currently get is that, if for instance I am doing an ajax calls on the client-side, the call doesn't seem to get there while the method above is executing. I would like it so that the method call executes in the background so that the client can still communicate with the server to execute other requests.
How can I handle this so that the user's client can make additional requests in the meantime?
The easiest solution is to change your session state to be None or Read-Only (for both this and the other requests). Then ASP.NET will allow multiple client requests for the same session.
If you're on pre-Core, the session state docs are here.
I need to execute some tasks after grails transaction ends. I'm not looking for afterCommit of Hibernate, instead of that, I need a method to be called after the transaction of the service ends.
Is there any way? I've read the documentation but I couldn't find anything, just normal events like afterUpdate or afterCommit.
Thanks!
You can add an event listener to the current session
sessionFactory.currentSession.addEventListener(...)
class MyListener extends BaseSessionEventListener {
#Override
void transactionCompletion(boolean successful) {
}
}
You just need to verify the transaction was successful via the parameter. Also understand that if there are multiple transactions in a single session the listener will be invoked for each one.
That really depends on what you're trying to do. The best bet is probably to call a #Transactional method on a service, and then when that returns, run the code that you need to happen after the transaction.
An alternative, if you just want to spin off some task to do something simple, you can use:
new java.util.Timer().runAfter(1000) { //time in milliseconds
//code to run here
}
This is just a shortcut to spin off a new thread and runs the closure body after (in the above example) 1 second... I believe the closure still has access to injected grails objects, but does not have access to the session. I'd double-check that though. I've used this in several places for sending notifications that needed to wait until after some processing inside a transaction ended.
We're running into a weird issue where objects are created in a first request, but they are not returned in a second request.
Let's assume we have two domain classes:
Class A {
static hasMany = [bs: B]
def afterUpdate() {
this.addToBs(new B(a: this))
this.save()
}
}
Class B {
static belongsTo = [a: A]
}
When a put is sent on an instance of A via PUT /as/<id>, update() is invoked in the RestfulController which is annotated with #Transactional.
What we can observe is, that every once in a while a follow-up request send by the API consumer after the response of the first request is returned, GET /bs does not return the new instance of B which should have been created in the first request and is also returned on further requests.
I'd expected that grails only sends the response to the API consumer once the transaction is committed, which would mean that the next request should see all changes from that transaction, shouldn't it?
What could be the reason for that behavior? Is the transaction committed after the grails app already sent the response to the API consumer? If so, is the reason the #Transactional around the update() which is turned on by default?
I know in this example the code in afterUpdate could probably also be put into beforeUpdate, but I just tried to to simplify the example as far as I could.
In my experience, code in afterUpdate() and the like are not included in the transaction. You'd have to create a transaction explicitly (and maybe a session too). See http://docs.grails.org/latest/ref/Domain%20Classes/withTransaction.html
I advise against GORM updates within afterUpdate() and friends because it leads to weird issues like this, and makes it difficult to unit test the domain models. If you delegate saving to a transactional service instead, not only would it just work, you'd also be able to confirm it with integration tests.
In my Grails apps, I keep my controllers really dumb:
Call a service
Return the service's output (possibly formatting it).
I keep all business logic in services because controllers are kind of a pain to test well. Here's an example:
#grails.transaction.Transactional
class SomeService {
def saveA(A a) {
// This method will run in a transaction.
a.addToBs(new B(a: this))
a.save()
}
}
And in the controller...
class SomeController {
def update() {
...
someService.save(a)
}
}
In Struts2 if we have define an interceptor stack and it is called in First in First Out manner.
So in post processing phase what happened if one of the earlier interceptor return a control string which in result render the response to the client.
I want to know that would the left interceptor will be processed or not.
Well it will work like this.
Your action method will only called once the interceptor stack has been called fully.This means that once the first interceptor has been called successfully in the stack it will call the next interceptor defined in the stack and there reference being stored in the stack this chain will keep on calling till the last interceptor in the stack is called
invocation.invoke()
this call is the key to call next interceptor defined in the stack or of this is the last it will call the desired function in your action class.
now in other case suppose some of the interceptor failed say workflow it will return the result as INPUT and will halt the further execution of the interceptor and framework will output the desired JSP/Tempelate to the user.
Than comes the post -processing/cleaning in this case interceptors will be called in reverse order i.e top most or latest executed interceptor will be called first and den so on so.
The idea for this post-processing is to do any clean-up work or any other things which needs to be done (like cleaning up resources etc)
Hope this will give you some idea.
The question is how could I stop a method being called twice, where the first call has not "completed" because its handler is waiting for a url to load for example?
Here is the situation:
I have written a flash client which interfaces with a java server using a binary encrypted protocol (I would love to not have had to re-invent the whole client/server object communcation stack, but I had to encrypt the data in such a way that simple tools like tamper data and charles proxy could not pick them up if using SSL).
The API presents itself to flas as an actionscript swf file, and the API itself is a singleton.
the api exposes some simple methods, including:
login()
getBalance()
startGame()
endGame()
Each method will call my HttpCommunicator class.
HttpCommunicator.as (with error handling and stuff removed):
public class HttpCommunicator {
private var _externalHalder:function;
public function communicate(data:String, externalHandler:APIHandler):void {
// do encryption
// add message numbers etc to data.
this._externalHalder = externalHandler;
request.data = encrypt(addMessageNumers(data)));
loader.addEventListener(Event.COMPLETE, handleComplete);
loader.load(request);
}
private function handleComplete(event:Event):void {
var loader:URLLoader = URLLoader(event.target);
String data = decrypt(loader.data);
// check message numbers match etc.
_externalHandler(data);
}
The problem with this is I cant protect the same HttpCommunicator object from being called twice before the first has handled the complete event, unless:
I create a new HttpCommunicator object every single time I want to send a message. I also want to avoid creating a URLLoader each time, but this is not my code so will be more problematic to know how it behaves).
I can do something like syncronize on communicate. This would effectivly block, but this is better than currupting the data transmission. In theory, the Flash client should not call the same api function twice in a row, but I but it will happen.
I implement a queue of messages. However, this also needs syncronization around the push and pop methods, which I cant find how to do.
Will option 1. even work? If I have a singleton with a method say getBalance, and the getBalance method has:
// class is instantiated through a factory as a singleton
public class API{
var balanceCommunicator:HttpCommunicator = new HttpCommunicator(); // create one for all future calls.
public funciton getBalance(playerId:uint, hander:Fuction):Number {
balanceCommunicator.communicate(...); // this doesnt block
// do other stuff
}
Will the second call trounce the first calls communicator variable? i.e. will it behave as if its static, as there is onlyone copy of the API object?
If say there was a button on the GUI which had "update balance", and the user kept clicking on it, at the same time as say a URLLoader complete event hander being called which also cals the apis getBalance() function (i.e. flash being multithreaded).
Well, first off, with the exception of the networking APIs, Flash is not multithreaded. All ActionScript runs in the same one thread.
You could fairly easily create a semaphore-like system where each call to communicate passed in a "key" as well as the arguments you already specified. That "key" would just be a string that represented the type of call you're doing (getBalance, login, etc). The "key" would be a property in a generic object (Object or Dictionary) and would reference an array (it would have to be created if it didn't exist).
If the array was empty then the call would happen as normal. If not then the information about the call would be placed into an object and pushed into the array. Your complete handler would then have to just check, after it finished a call, if there were more requests in the queue and if so dequeue one of them and run that request.
One thing about this system would be that it would still allow different types of requests to happen in parallel - but you would have to have a new URLLoader per request (which is perfectly reasonable as long as you clean it up after each request is done).