OCA / odoorpc

Python module to pilot your Odoo servers through JSON-RPC.
http://pythonhosted.org/OdooRPC/
GNU Lesser General Public License v3.0
231 stars 123 forks source link

API calls cause `socket.timeout: timed out`, sometimes #76

Closed sguldemond closed 2 years ago

sguldemond commented 2 years ago

From time to time I get the similar messages when I am communicating with Odoo via odoorpc:

2022-06-28 14:19:07.590 | ERROR    | invopro.rmq.interface:do_work:75 - timed out
Traceback (most recent call last):

  File "/usr/lib/python3.9/threading.py", line 912, in _bootstrap
    self._bootstrap_inner()
    │    └ <function Thread._bootstrap_inner at 0x7fa0b5802ca0>
    └ <Thread(Thread-334, started 140327654520576)>
  File "/usr/lib/python3.9/threading.py", line 954, in _bootstrap_inner
    self.run()
    │    └ <function Thread.run at 0x7fa0b58029d0>
    └ <Thread(Thread-334, started 140327654520576)>
  File "/usr/lib/python3.9/threading.py", line 892, in run
    self._target(*self._args, **self._kwargs)
    │    │        │    │        │    └ {}
    │    │        │    │        └ <Thread(Thread-334, started 140327654520576)>
    │    │        │    └ (<BlockingConnection impl=<SelectConnection OPEN transport=<pika.adapters.utils.io_services_utils._AsyncPlaintextTransport ob...
    │    │        └ <Thread(Thread-334, started 140327654520576)>
    │    └ <function RMQInterface.consume_task_queues.<locals>.do_work at 0x7fa0b4b2f5e0>
    └ <Thread(Thread-334, started 140327654520576)>

> File "/home/invopro/src/invopro_project/invopro/rmq/interface.py", line 73, in do_work
    handler.perform_task()
    │       └ <function AccountMoveEDIStateChangeHandler.perform_task at 0x7fa0ab0a50d0>
    └ <invopro.tasks.handler.AccountMoveEDIStateChangeHandler object at 0x7fa0a8924f40>

  File "/home/invopro/src/invopro_project/invopro/tasks/handler.py", line 231, in perform_task
    customer = get_partner_by_id(customer_id)
               │                 └ 2105
               └ <function get_partner_by_id at 0x7fa0abbdd820>

  File "/home/invopro/src/invopro_project/invopro/odoo/crud/partner.py", line 52, in get_partner_by_id
    partner = _build_partner_object(partner_data, extended)
              │                     │             └ False
              │                     └ Recordset('res.partner', [2105])
              └ <function _build_partner_object at 0x7fa0abbdd940>

  File "/home/invopro/src/invopro_project/invopro/odoo/crud/partner.py", line 85, in _build_partner_object
    gln_numbers = [x.number for x in partner_data.gln_number_ids]
                                     │            └ <odoorpc.fields.Many2many object at 0x7fa0aa6c6160>
                                     └ Recordset('res.partner', [2105])

  File "/home/invopro/venv/lib/python3.9/site-packages/odoorpc/fields.py", line 401, in __get__
    orig_ids = instance._odoo.execute_kw(
               │        │     └ <function ODOO.execute_kw at 0x7fa0abbd6dc0>
               │        └ <odoorpc.odoo.ODOO object at 0x7fa0a89da700>
               └ Recordset('res.partner', [2105])
  File "/home/invopro/venv/lib/python3.9/site-packages/odoorpc/odoo.py", line 482, in execute_kw
    data = self.json(
           │    └ <function ODOO.json at 0x7fa0abbd6a60>
           └ <odoorpc.odoo.ODOO object at 0x7fa0a89da700>
  File "/home/invopro/venv/lib/python3.9/site-packages/odoorpc/odoo.py", line 271, in json
    data = self._connector.proxy_json(url, params)
           │    │          │          │    └ {'service': 'object', 'method': 'execute_kw', 'args': ['Abel_Staging', 2, 'xxx', 'res.partner', 'read', [[21...
           │    │          │          └ '/jsonrpc'
           │    │          └ <property object at 0x7fa0abef1f40>
           │    └ <odoorpc.rpc.ConnectorJSONRPC object at 0x7fa0aa5b1610>
           └ <odoorpc.odoo.ODOO object at 0x7fa0a89da700>
  File "/home/invopro/venv/lib/python3.9/site-packages/odoorpc/rpc/jsonrpclib.py", line 113, in __call__
    response = self._opener.open(request, timeout=self._timeout)
               │    │       │    │                │    └ 120.0
               │    │       │    │                └ <odoorpc.rpc.jsonrpclib.ProxyJSON object at 0x7fa0ab24adc0>
               │    │       │    └ <urllib.request.Request object at 0x7fa0aa6c6910>
               │    │       └ <function OpenerDirector.open at 0x7fa0abc628b0>
               │    └ <urllib.request.OpenerDirector object at 0x7fa0ab24a7c0>
               └ <odoorpc.rpc.jsonrpclib.ProxyJSON object at 0x7fa0ab24adc0>
  File "/usr/lib/python3.9/urllib/request.py", line 517, in open
    response = self._open(req, data)
               │    │     │    └ None
               │    │     └ <urllib.request.Request object at 0x7fa0aa6c6910>
               │    └ <function OpenerDirector._open at 0x7fa0abc62940>
               └ <urllib.request.OpenerDirector object at 0x7fa0ab24a7c0>
  File "/usr/lib/python3.9/urllib/request.py", line 534, in _open
    result = self._call_chain(self.handle_open, protocol, protocol +
             │    │           │    │            │         └ 'http'
             │    │           │    │            └ 'http'
             │    │           │    └ {'unknown': [<urllib.request.UnknownHandler object at 0x7fa0ab24adf0>], 'http': [<urllib.request.HTTPHandler object at 0x7fa0...
             │    │           └ <urllib.request.OpenerDirector object at 0x7fa0ab24a7c0>
             │    └ <function OpenerDirector._call_chain at 0x7fa0abc62820>
             └ <urllib.request.OpenerDirector object at 0x7fa0ab24a7c0>
  File "/usr/lib/python3.9/urllib/request.py", line 494, in _call_chain
    result = func(*args)
             │     └ (<urllib.request.Request object at 0x7fa0aa6c6910>,)
             └ <bound method HTTPHandler.http_open of <urllib.request.HTTPHandler object at 0x7fa0ab24a310>>
  File "/usr/lib/python3.9/urllib/request.py", line 1375, in http_open
    return self.do_open(http.client.HTTPConnection, req)
           │    │       │    │      │               └ <urllib.request.Request object at 0x7fa0aa6c6910>
           │    │       │    │      └ <class 'http.client.HTTPConnection'>
           │    │       │    └ <module 'http.client' from '/usr/lib/python3.9/http/client.py'>
           │    │       └ <module 'http' from '/usr/lib/python3.9/http/__init__.py'>
           │    └ <function AbstractHTTPHandler.do_open at 0x7fa0abc15310>
           └ <urllib.request.HTTPHandler object at 0x7fa0ab24a310>
  File "/usr/lib/python3.9/urllib/request.py", line 1350, in do_open
    r = h.getresponse()
        │ └ <function HTTPConnection.getresponse at 0x7fa0abc0d4c0>
        └ <http.client.HTTPConnection object at 0x7fa0a89d3940>
  File "/usr/lib/python3.9/http/client.py", line 1347, in getresponse
    response.begin()
    │        └ <function HTTPResponse.begin at 0x7fa0abc0c820>
    └ <http.client.HTTPResponse object at 0x7fa0a89d3730>
  File "/usr/lib/python3.9/http/client.py", line 307, in begin
    version, status, reason = self._read_status()
                              │    └ <function HTTPResponse._read_status at 0x7fa0abc0c790>
                              └ <http.client.HTTPResponse object at 0x7fa0a89d3730>
  File "/usr/lib/python3.9/http/client.py", line 268, in _read_status
    line = str(self.fp.readline(_MAXLINE + 1), "iso-8859-1")
               │    │           └ 65536
               │    └ None
               └ <http.client.HTTPResponse object at 0x7fa0a89d3730>
  File "/usr/lib/python3.9/socket.py", line 704, in readinto
    return self._sock.recv_into(b)
           │    │               └ <memory at 0x7fa0aaf89700>
           │    └ None
           └ <socket.SocketIO object at 0x7fa0a89d34c0>

socket.timeout: timed out

An example of code that I use is this, which might be called every 30 seconds or so:

def _post_invoice(id: int):
        odoo = odoorpc.ODOO(config.ODOO_HOST, port=config.ODOO_PORT)
        odoo.login(config.ODOO_DB_NAME, config.ODOO_USER, config.ODOO_PASS)
        try:
            odoo.json(
                "/web/dataset/call_button",
                {
                    "model": "account.move",
                    "method": "action_post",
                    "args": [[id]],
                    "kwargs": {},
                },
            )
            logger.debug(f"Posted invoice [id = {id}]")
        except RPCError as e:
            raise e

But it can occur with any call to the API.

It seems to be like Odoo is busy, and timed out the API call. Does anyone know why this is causes, maybe how to deal with it?

sguldemond commented 2 years ago

I think I can just adjust the timeout value in this call:

odoo = odoorpc.ODOO(config.ODOO_HOST, port=config.ODOO_PORT, timeout=240)