'This method runs @plugin with FuzzableRequest as parameter and returns
new fuzzable requests and/or stores vulnerabilities in the knowledge
base.
Since threadpool\'s apply_async runs the callback only when the call to
this method ends without any exceptions, it is *very important* to
handle exceptions correctly here. Failure to do so will end up in
_task_done not called, which will make has_pending_work always return
True.
Python 3 has an error_callback in the apply_async method, which we could
use in the future.
TODO: unit-test this method
:return: A list with the newly found fuzzable requests.'

@task_decorator
def _discover_worker(self, function_id, plugin, fuzzable_request):

    args = (plugin.get_name(), fuzzable_request.get_uri())
    om.out.debug(('Called    _discover_worker(%s,%s)' % args))
    status = self._w3af_core.status
    status.set_running_plugin('crawl', plugin.get_name())
    status.set_current_fuzzable_request('crawl', fuzzable_request)
    om.out.debug(('%s    is    testing    "%s"' % (plugin.get_name(), fuzzable_request.get_uri())))
    try:
        result = plugin.discover_wrapper(fuzzable_request)
    except BaseFrameworkException as e:
        msg = 'An    exception    was    found    while    running    "%s"    with    "%s":    "%s".'
        om.out.error((msg % (plugin.get_name(), fuzzable_request)), e)
    except RunOnce:
        self._remove_discovery_plugin(plugin)
    except Exception as e:
        self.handle_exception(plugin.get_type(), plugin.get_name(), fuzzable_request, e)
    else:
        if (result is not None):
            msg = ('The    %s    plugin    did    NOT    return    None.' % plugin.get_name())
            ve = ValueError(msg)
            self.handle_exception(plugin.get_type(), plugin.get_name(), fuzzable_request, ve)
