I am developing in a Grails application. What I want to do is to lock the request/response, create a promise, and let someone else resolve it, that is somewhere else in the code, and then flush the response.
What I find really strange is that the Promise promise = task {} interface has no method that resembles resolve or similar.
I need to lock the response until someone resolves the promise, which is a global/static property set in development mode.
Promise interface: http://grails.org/doc/latest/api/grails/async/Promise.html
I have looked at the GPars doc and can't find anything there that resembles a resolve method.
How can I create a promise, that locks the response or request, and then flushes the response when someone resolves it?
You can call
get()
on the promise which will block until whatever the task is doing completes, but I imagine what that is not what you want. What you want seems to be equivalent to a GParsDataflowVariable
:http://gpars.org/1.0.0/javadoc/groovyx/gpars/dataflow/DataflowVariable.html
Which allows using the left shift operator to resolve the value from another thread. Currently there is no way to use the left shift operator via Grails directly, but since Grails' promise API is just a layer over GPars this can probably be accomplished by using the GPars API directly with something like:
It took me quite some time to get around this and have a working answer.
I must say that it appears as if Grails is quite a long way of making this work properly.
task { }
will always execute immediatly, so the call is not put on hold until dispatch() or whatever is invoked which is a problem.
Try this to see:
If you are wondering what this is for, it is to make the lesscss refresh automatically in grails, which is a problem when you are using import statements in less. When the file is touched, the lesscss compiler will trigger a recompilation, and only when it is done should it respond to the client.
On the client side I have some javascript that keeps replacing the last using the refresh action here:
In my controller:
A class written for this:
In LesscssResourceMapper.groovy of the lesscsss-recources plugin:
In the index.gsp file:
JavaScript method refreshResources to replace the previous link href=...
Comments
I am unsure why Javascript style promises have not been added to the Grails stack. You can not render or stuff like that in the onComplete. render, redirect and what not are not available.
Something tells me that Grails and Promises/Futures are not there yet. The design of the GPars libraries seems not take into account of the core features which is to resolve later. At least it is not simple to do so.
It would be great if the dispatch() method actually could be invoked with some paramaters to pass from the resolving context. I am able to go around this using static properties.
I might continue to write my own solution and possibly contribute with a more fitting solutions around the AsyncContext class, but for now, this is enough for me.
I just wanted to refresh my less resources automatically.
Phew...
EDIT:
I made it to support several number of files. It is complete now!