← Back to team overview

c2c-oerpscenario team mailing list archive

Re: [Bug 740361] Re: [account] slow large invoice validation because validate is called for every line

 

Guys, can anyone confirm what Amit said?
In my tests, the validate method is called as many times as I have invoice
lines, which is very very problematic here. Customer with 50 lines need to
wait 2 minutes to have their invoice validated, call it an improvement...
I'm not sure this will encourage my customer o buy an OPW :-(

On Fri, May 6, 2011 at 9:39 AM, Amit Parik (OpenERP)
<amp@xxxxxxxxxxx>wrote:

> Hello,
>
> I have checked your issue and there is doesn't matter how many invoice
> lines are there.
> But the def validate method call three time when we validate the invoice.
>
> And this is not a bug it's improvement.
> So I am set it as a "Triaged" and the related team will check the patch and
> they will decided.
>
> Thanks for the understanding!
>
> ** Summary changed:
>
> - [6.0.1][account] slow large invoice validation because validate is called
> for every line
> + [account] slow large invoice validation because validate is called for
> every line
>
> ** Changed in: openobject-addons
>   Importance: Undecided => Low
>
> ** Changed in: openobject-addons
>       Status: New => Triaged
>
> ** Changed in: openobject-addons
>     Assignee: (unassigned) => OpenERP R&D Addons Team 3
> (openerp-dev-addons3)
>
> --
> You received this bug notification because you are a member of OpenERP
> Drivers, which is subscribed to OpenERP Addons.
> https://bugs.launchpad.net/bugs/740361
>
> Title:
>   [account] slow large invoice validation because validate is called for
>  every line
>
> Status in OpenERP Modules (addons):
>   Triaged
>
> Bug description:
>  edit account/account.py
>  and introduce some traceback print statement this way:
>
>  @@ -1378,6 +1385,9 @@
>       # Validate a balanced move. If it is a centralised journal, create a
> move.
>       #
>       def validate(self, cr, uid, ids, context=None):
>  +#        import traceback
>  +#        traceback.print_stack()
>  +        print "validate", ids
>           if context and ('__last_update' in context):
>               del context['__last_update']
>
>
>  Now restart your server and try to validate an invoice with many lines,
> like 10 (cool you are not in production).
>  As you can see, that slow validate method is called for every invoice
> line, making the whole process very slow. Here in production it takes like 2
> minutes to validate a 50 lines (with Brazilian taxes) invoice... Not very
> user friendly.
>
>  You'll see a similar traceback for every line:
>
>    File "/opt/openerp-trunk/server/bin/osv/orm.py", line 181, in <lambda>
>      return lambda *args, **argv: attr(self._cr, self._uid, [self._id],
> *args, **argv)
>    File "/opt/openerp-trunk/addons/l10n_br_account/invoice.py", line 323,
> in action_move_create
>      self.pool.get('account.move.line').write(cr, uid, [move_line.id for
> move_line in inv.move_id.line_id], {'ref': inv.internal_number})
>    File
> "/opt/openerp-trunk/addons/account_payment_extension/account_move_line.py",
> line 168, in write
>      return super(account_move_line, self).write(cr, uid, ids, vals,
> context, check, update_check)
>    File "/opt/openerp-trunk/addons/account/account_move_line.py", line
> 1171, in write
>      result = super(account_move_line, self).write(cr, uid, ids, vals,
> context)
>    File "/opt/openerp-trunk/server/bin/osv/orm.py", line 3414, in write
>      result += self._columns[field].set(cr, self, id, field, vals[field],
> user, context=rel_context) or []
>    File "/opt/openerp-trunk/server/bin/osv/fields.py", line 830, in set
>      self._fnct_inv(obj, cr, user, id, name, value, self._fnct_inv_arg,
> context)
>    File "/opt/openerp-trunk/server/bin/osv/fields.py", line 881, in
> _fnct_write
>      model.write(cr, uid, [t_id], {args[-1]: values}, context=context)
>    File "/opt/openerp-trunk/addons/account/account.py", line 1240, in write
>      self.validate(cr, uid, ids, context=context)
>    File "/opt/openerp-trunk/addons/account/account.py", line 1389, in
> validate
>      traceback.print_stack()
>  validate [543]
>
>
>  In "/opt/openerp-trunk/addons/account/account_move_line.py", line 1171, in
> write we still have a table of ids, so the hell loop is not born yet.
>  It will actually birth inside the ORM in
> "/opt/openerp-trunk/server/bin/osv/orm.py", line 3414, in write
>  where you'll iterate over each id.
>  I tend to think this is a first bad implementation, may be the real source
> of the bug. After this, we call validate for each account move line...
>
>
>  Still, it looks like you attempted to prevent this by strong a context
> c['novalidate'] = True flag.
>  a grep gives us:
>
>  ~# grep -r novalidate /opt/openerp-trunk/addons/account/
>  /opt/openerp-trunk/addons/account/account.py:        c['novalidate'] =
> True
>  /opt/openerp-trunk/addons/account/account.py:            c['novalidate'] =
> True
>
>  But as you can see, it's a bit like marketing: totally useless. Sounds
>  like a good intention but it has absolutely no effect at all, it's
>  just no used.
>
>  So, I let you determine what is the proper fix, something in the ORM
>  or some "novalidate" trickery before somebody remove the trick by
>  mistake again to fox some side effect bug...
>
>  Hope this helps.
>

-- 
You received this bug notification because you are a member of C2C
OERPScenario, which is subscribed to the OpenERP Project Group.
https://bugs.launchpad.net/bugs/740361

Title:
  [account] slow large invoice validation because validate is called for
  every line

Status in OpenERP Modules (addons):
  Triaged

Bug description:
  edit account/account.py
  and introduce some traceback print statement this way:

  @@ -1378,6 +1385,9 @@
       # Validate a balanced move. If it is a centralised journal, create a move.
       #
       def validate(self, cr, uid, ids, context=None):
  +#        import traceback
  +#        traceback.print_stack()
  +        print "validate", ids
           if context and ('__last_update' in context):
               del context['__last_update']

  
  Now restart your server and try to validate an invoice with many lines, like 10 (cool you are not in production).
  As you can see, that slow validate method is called for every invoice line, making the whole process very slow. Here in production it takes like 2 minutes to validate a 50 lines (with Brazilian taxes) invoice... Not very user friendly.

  You'll see a similar traceback for every line:

    File "/opt/openerp-trunk/server/bin/osv/orm.py", line 181, in <lambda>
      return lambda *args, **argv: attr(self._cr, self._uid, [self._id], *args, **argv)
    File "/opt/openerp-trunk/addons/l10n_br_account/invoice.py", line 323, in action_move_create
      self.pool.get('account.move.line').write(cr, uid, [move_line.id for move_line in inv.move_id.line_id], {'ref': inv.internal_number})
    File "/opt/openerp-trunk/addons/account_payment_extension/account_move_line.py", line 168, in write
      return super(account_move_line, self).write(cr, uid, ids, vals, context, check, update_check)
    File "/opt/openerp-trunk/addons/account/account_move_line.py", line 1171, in write
      result = super(account_move_line, self).write(cr, uid, ids, vals, context)
    File "/opt/openerp-trunk/server/bin/osv/orm.py", line 3414, in write
      result += self._columns[field].set(cr, self, id, field, vals[field], user, context=rel_context) or []
    File "/opt/openerp-trunk/server/bin/osv/fields.py", line 830, in set
      self._fnct_inv(obj, cr, user, id, name, value, self._fnct_inv_arg, context)
    File "/opt/openerp-trunk/server/bin/osv/fields.py", line 881, in _fnct_write
      model.write(cr, uid, [t_id], {args[-1]: values}, context=context)
    File "/opt/openerp-trunk/addons/account/account.py", line 1240, in write
      self.validate(cr, uid, ids, context=context)
    File "/opt/openerp-trunk/addons/account/account.py", line 1389, in validate
      traceback.print_stack()
  validate [543]

  
  In "/opt/openerp-trunk/addons/account/account_move_line.py", line 1171, in write we still have a table of ids, so the hell loop is not born yet.
  It will actually birth inside the ORM in "/opt/openerp-trunk/server/bin/osv/orm.py", line 3414, in write
  where you'll iterate over each id.
  I tend to think this is a first bad implementation, may be the real source of the bug. After this, we call validate for each account move line...

  
  Still, it looks like you attempted to prevent this by strong a context c['novalidate'] = True flag.
  a grep gives us:

  ~# grep -r novalidate /opt/openerp-trunk/addons/account/
  /opt/openerp-trunk/addons/account/account.py:        c['novalidate'] = True
  /opt/openerp-trunk/addons/account/account.py:            c['novalidate'] = True

  But as you can see, it's a bit like marketing: totally useless. Sounds
  like a good intention but it has absolutely no effect at all, it's
  just no used.

  So, I let you determine what is the proper fix, something in the ORM
  or some "novalidate" trickery before somebody remove the trick by
  mistake again to fox some side effect bug...

  Hope this helps.


References