3

In my project, the action of my Grails controller is creating a new thread and calling a class form src/groovy folder each time this action is executed. I need to pass the value from this action to the new thread being created. How can I achieve this?

Update: I am implementing crawler4j in my project.

My controller code is as follows: Thanks in advance.

class ResourceController{
def crawl(Integer max) {
    String crawlStorageFolder = ".crawler4j";
    String website = "www.google.com";
    controller.startNonBlocking(BasicCrawler.class, numberOfCrawlers); //this line after a series of background tasks calls the BasicCrawler class located in src/groovy. 
    Thread.sleep(30 * 1000);
}

The crawler4j starts a new thread when it calls the BasicCrawler class.

The BasicCrawler class has a visit function. I need to pass value of website from ResourceController to the visit function.

clever_bassi
  • 2,392
  • 2
  • 24
  • 43
  • 1
    You are going to have to provide samples of how you are doing this, otherwise it's impossible to answer your question. – Joshua Moore Aug 25 '14 at 17:42

1 Answers1

0

So if I were doing this I'd change it so that the caller instantiates the class it wants to run off thread that way it can pass whatever data you want to it as opposed to passing only a class and having the framework instantiate it for me. If you are using Grails 2.3+ then you can just use promises like this:

import static grails.async.Promises.*

class ResourceController {
   def crawl(Integer max) {
       Map<String,String> sharedObject = [someProperty: 'blah', someOtherProperty: 'blahblah'];
       List<Promise> promises = []
       numberOfCrawlers.times {
          promises << task {
              doSomethingOffThread( sharedObject.someProperty );
          }

          promises.last().onComplete { result -> log.info("background job done.") }
       }      
   }
}

Be aware that data being shared in this manner should only be read-only. Otherwise you'll have concurrency issues to contend with. Treat this as efficient message passing, and do not modify the shared objects and you can avoid dealing with synchronization. The promise can return data back to the caller through promise.get() or promise.onComplete so there is little need to modify the actual input objects.

http://grails.org/doc/2.3.0.M1/guide/async.html

chubbsondubs
  • 37,646
  • 24
  • 106
  • 138