Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Exception on closing context #96

Open
mattclarke opened this issue Dec 19, 2022 · 4 comments
Open

Exception on closing context #96

mattclarke opened this issue Dec 19, 2022 · 4 comments
Assignees
Labels

Comments

@mattclarke
Copy link

On version 4.1.5 when closing the context or stopping the script I get the following:

P4P atexit completes
AttributeError: '_ClientProvider' object has no attribute 'close'
Exception ignored in: 'p4p._p4p.ClientProvider.__dealloc__'
AttributeError: '_ClientProvider' object has no attribute 'close'

This is on a Mac.
I don't see this on 4.1.2, but see it on all later versions.

@mdavidsaver
Copy link
Member

What python version is involved? Which concurrency method? (thread, cothread, asyncio, Qt?)

This is probably another instance of GC loop breaking Having partially disassembled the object. The _ClientProvider extension type certainly does have a close() method, at least prior to GC.

I'm tempted to decorate all of my Cython extension types with @cython.no_gc_clear, although this would likely just push GC loop breaking to some other equally unexpected place.

@mdavidsaver mdavidsaver self-assigned this May 31, 2023
@mattclarke
Copy link
Author

Sorry I should have added the python version to the report.
Unfortunately, the Mac I saw it on was replaced and I cannot reproduce it on my new one.
Let's file it as "cannot reproduce" and if I see it again in the future I'll reopen this with an update report.

@coretl
Copy link
Collaborator

coretl commented Aug 7, 2023

I've just stumbled upon this while reporting #115. Running a p4p server then a p4p asyncio client that raises a remote exception seems to trigger it.

Run the server:

# p4p_server.py
from p4p.nt import NTScalar
from p4p.server import Server
from p4p.server.thread import SharedPV

pv = SharedPV(nt=NTScalar('ai'), initial=[1,2,3])  # int32 array

@pv.put
def handle(pv, op):
    v = op.value()
    print(f"Updating to {v}")
    pv.post(v) # just store and update subscribers
    op.done()

Server.forever(providers=[{
    'demo:pv:name':pv, 
}])

Then run the client:

# p4p_client.py
from p4p.client.asyncio import Context
import numpy as np
import asyncio

pv = 'demo:pv:name'

async def f():
    with Context("pva", nt=False) as c:
        print(f"Initial: {(await c.get(pv)).value}")
        await c.put(pv, [4, 5, 6])
        print(f"List works: {(await c.get(pv)).value}")
        await c.put(pv, np.array([7, 8, 9]))
        print(f"Np.int64 array doesn't: {(await c.get(pv)).value}")
          
asyncio.run(f())

Server gives a remote exception, then client gives output:

Initial: [1 2 3]
List works: [4 5 6]
Exception in Put builder
Traceback (most recent call last):
  File "/venv/lib/python3.10/site-packages/p4p/client/raw.py", line 80, in builder
    nt.assign(V, value)
  File "/venv/lib/python3.10/site-packages/p4p/nt/__init__.py", line 84, in assign
    self._assign(V, value)
  File "/venv/lib/python3.10/site-packages/p4p/nt/__init__.py", line 100, in _default_assign
    V.value = value # assume NTScalar-like
  File "src/p4p/_p4p.pyx", line 223, in p4p._p4p._Value.__setattr__
TypeError: Cannot cast array data from dtype('int64') to dtype('int32') according to the rule 'safe'
Unhandled Exception src/pvxs_client.cpp:67
Traceback (most recent call last):
  File "/venv/lib/python3.10/site-packages/p4p/client/raw.py", line 80, in builder
    nt.assign(V, value)
  File "/venv/lib/python3.10/site-packages/p4p/nt/__init__.py", line 84, in assign
    self._assign(V, value)
  File "/venv/lib/python3.10/site-packages/p4p/nt/__init__.py", line 100, in _default_assign
    V.value = value # assume NTScalar-like
  File "src/p4p/_p4p.pyx", line 223, in p4p._p4p._Value.__setattr__
TypeError: Cannot cast array data from dtype('int64') to dtype('int32') according to the rule 'safe'
Traceback (most recent call last):
  File "/dls/science/users/tmc43/repos/.devcontainer/./p4p_client_asyncio.py", line 15, in <module>
    asyncio.run(f())
  File "/usr/lib/python3.10/asyncio/runners.py", line 44, in run
    return loop.run_until_complete(main)
  File "/usr/lib/python3.10/asyncio/base_events.py", line 646, in run_until_complete
    return future.result()
  File "/dls/science/users/tmc43/repos/.devcontainer/./p4p_client_asyncio.py", line 12, in f
    await c.put(pv, np.array([7, 8, 9]))
  File "/venv/lib/python3.10/site-packages/p4p/client/asyncio.py", line 207, in put
    return (await self._put_one(name, values, request=request, get=get))
  File "/venv/lib/python3.10/site-packages/p4p/client/asyncio.py", line 236, in _put_one
    value = await F
p4p._p4p.RemoteError: Unable to unwrap Value(id:epics:nt/NTScalarArray:1.0, None) with <bound method NTScalar.unwrap of <class 'p4p.nt.scalar.NTScalar'>>
Traceback (most recent call last):
  File "src/p4p/_p4p.pyx", line 634, in p4p._p4p.ClientProvider.close
AttributeError: '_ClientProvider' object has no attribute 'close'
Exception ignored in: 'p4p._p4p.ClientProvider.__dealloc__'
Traceback (most recent call last):
  File "src/p4p/_p4p.pyx", line 634, in p4p._p4p.ClientProvider.close
AttributeError: '_ClientProvider' object has no attribute 'close'

Running on Linux with python 3.10.6, p4p 4.1.9, pvxslibs 1.2.2, epicscorelibs 7.0.7.99.0.2

@mdavidsaver
Copy link
Member

As it happens, I managed to trigger this issue today and have made another attempt at fixing with 546b919

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants