Folks, In the Estatio app we have a couple of actions that take a long time to run. We hope to improve the algorithm such that they respond more timely; even so, we're thinking of how to address long-running tasks.
We're still kicking around the ideas on this, but I'm starting to implement pieces anyway. ~~~ The first part of the puzzle that I've gone ahead and implemented [1] is actually a pair of services, namely * InteractionContext - a request-scoped service that provides acccess to an "Interaction" object, hold information on the action being performed by the user, and * InteractionFactory - making the implementation of "Interaction" pluggable. I've also done a JDO implementation of InteractionFactory. With this configured (eg as per the todo app), it means that every action invoked by the user results in an Interaction object being persisted. Among other things, this is pretty useful for profiling - to see the duraction of each action. ~~~ The next idea I have is to provide a "BackgroundService" that would allow a long-running task to instead create subtasks that can then be run asynchronously, eg by Quartz scheduler. My idea is that the code to create subtasks would be something like: public void calculateInvoices() { for(Customer customer: customerRepository.findCustomersToInvoice()) { backgroundService.execute(customer).calculateInvoice(); } } @javax.inject.Inject private BackgroundService backgroundService; The idea here is that the "execute(...)" method would actually return a javassist proxy around the domain object, in the same way that mock frameworks and our own existing WrapperFactory [2] do. Thus, the "calcuateInvoice(...)" action - or whatever is to be run in the background - is called upon the proxy. This allows the proxy to get hold of the target and the action params. Rather than executing the action immediately, the idea instead is that the proxy creates a memento out of the action, using the MementoService [3,4]. This can then be persisted as a new entity, BackgroundTask, say. Using Quartz scheduler, this can then poll for these BackgroundTasks and execute them. ~~~ In the UI, what we want is to be able to show the user the state of these background tasks. This is where the (persisted) Interaction comes in. Because InteractionContext is injected, it is avaiable to the persisted BackgroundTasks. They can therefore associate themselves with these tasks. We can then use a contributed collection to Interaction. The net result should be that, when a user views the Interactions, then they will see a collection of BackgroundTasks underneath. Anyway, that's where I'm at. I suspect these ideas will develop further this week. Comments welcome, as ever. Cheers Dan [1] https://issues.apache.org/jira/browse/ISIS-660 [2] http://isis.apache.org/core/wrapper.html [3] https://issues.apache.org/jira/browse/ISIS-593 [4] https://issues.apache.org/jira/browse/ISIS-640