Skip to content

Commit

Permalink
Fix auto registration of job methods and channels
Browse files Browse the repository at this point in the history
The automatic registration of job methods and their defaut channel
has been a bit chaotic. The initial version for the new Odoo API could
crashing as soon as a method was decorated by @Property. There is
such a property in the code code, the method '_cache'.

The problem of the crash was that, the introspection basically uses a
'getattr' on every attribute of the instance. The '_cache' method
could then be called on an empty recordset, which is not supported by
'_cache'.

A first correction (49d8f37) was to naively skip the '_cache' method
from the introspection.

In any case, it is wrong to access the property of an instance only to
instrospect its members.  That's why the correction 4ebb245 changed the
inspection from the instance to the class.

Properties are no longer accessed, however this correction was not
correct for Python 3. When members of the class are introspected, they
are neither bound neither unbound methods. they are mere functions.

The change here is to lookup for functions. _register_job must now takes
the model as input argument, because there is no way to get the name of
the model from the function.

Closes OCA#64
Follows OCA#50
  • Loading branch information
guewen authored and eantones committed Oct 16, 2020
1 parent 1ef902d commit 8c219f3
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 7 deletions.
4 changes: 2 additions & 2 deletions queue_job/models/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ def _register_hook(self):
super(Base, self)._register_hook()
job_methods = [
method for __, method
in inspect.getmembers(self.__class__, predicate=inspect.ismethod)
in inspect.getmembers(self.__class__, predicate=inspect.isfunction)
if getattr(method, 'delayable', None)
]
for job_method in job_methods:
self.env['queue.job.function']._register_job(job_method)
self.env['queue.job.function']._register_job(self, job_method)

@api.multi
def with_delay(self, priority=None, eta=None,
Expand Down
10 changes: 5 additions & 5 deletions queue_job/models/queue_job.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@
_logger = logging.getLogger(__name__)


def channel_func_name(method):
return '<%s>.%s' % (method.__self__._name, method.__name__)
def channel_func_name(model, method):
return '<%s>.%s' % (model._name, method.__name__)


class QueueJob(models.Model):
Expand Down Expand Up @@ -102,7 +102,7 @@ def _compute_job_function(self):
for record in self:
model = self.env[record.model_name]
method = getattr(model, record.method_name)
channel_method_name = channel_func_name(method)
channel_method_name = channel_func_name(model, method)
func_model = self.env['queue.job.function']
function = func_model.search([('name', '=', channel_method_name)])
record.channel_method_name = channel_method_name
Expand Down Expand Up @@ -352,8 +352,8 @@ def _find_or_create_channel(self, channel_path):
return channel

@api.model
def _register_job(self, job_method):
func_name = channel_func_name(job_method)
def _register_job(self, model, job_method):
func_name = channel_func_name(model, job_method)
if not self.search_count([('name', '=', func_name)]):
channel = self._find_or_create_channel(job_method.default_channel)
self.create({'name': func_name, 'channel_id': channel.id})

0 comments on commit 8c219f3

Please sign in to comment.