EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  <20162017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  <20162017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: Re: Is There A Way to Explicitly Close CA Connections in PyEpics?
From: Weiwei Lu <[email protected]>
To: Matt Newville <[email protected]>
Cc: tech-talk <[email protected]>
Date: Fri, 19 Aug 2016 11:50:44 -0400 (EDT)
Hi Matt,

Many thanks for the suggestions.

> What version of pyepics are you using?

I think I am using pyepics-3.2.1, but not 100% sure.  Is there a command that can tell which version I am using?

> Why do you want to do this?

Well, just wanted to make the program more ioc friendly.  Closing the unused connections releases the resources (file descriptors, memory) of the iocs.  My program is a daemon program.  If it does not close the connections it has opened and are no longer needed, those connections will remain open forever.  Also how about the unresolved pv searches; will my program keeps searching those unresolved pvs forever if it does not close them explicitly?  So I think by closing the unused or unresolved pvs, these problems can be avoided.

>    import gc
>    gc.collect()

Calling gc.collect() after executing pv = None, the connection remained open.  So this does not work.

>    epics.ca.clear_channel(chid)
>    ctx =epics.ca.current_context()
>    epics.ca._cache[ctx].pop(pvname)

Yes, this works!  This clears the connection and also allows re-creation of a channel on the same pv.

Cheers,
William

----- Original Message -----
From: "Matt Newville" <[email protected]>
To: "weiwei" <[email protected]>
Cc: "tech-talk" <[email protected]>
Sent: Thursday, August 18, 2016 2:04:41 PM
Subject: Re: Is There A Way to Explicitly Close CA Connections in PyEpics?

Hi Weiwei,
On Thu, Aug 18, 2016 at 11:21 AM, Weiwei Lu <[email protected]> wrote:
>
> Hello,
>
> I am writing a Python (2.7.5) program and are using PyEpics in the
program.  I wanted to explicitly close the CA connections after I created
and used them, but found that once a CA connection was created, it stayed
connected (the ioc server was up) until the program exited, and there seems
to be no way to close it explicitly in the program.  I am new to the
PyEpics and appreciate any help.


A couple of suggestions / meta-questions before answering your specific
question:

First, Python 2.7.5 is slightly old (~3 years).  What version of pyepics
are you using?

Second,  usually pyepics uses connection callbacks and so handles the ioc
server going down and coming back without problem (that is, the PVs
re-establish the connection).  I'm not sure it's really necessary to
completely close the CA connections for particular PVs.  Why do you want to
do this?

Pyepics tries hard to retain the connections for CA channels, including
keeping connection callbacks,  and get callbacks in global state, and for
each threading "context".    This is held in 'epics.ca._cache', a
dictionary with keys that are the context (from ca.current_context()) and
values that are also dictionaries, now keyed by channel name, with values
that include several pieces of information, including pointers to
connection callbacks (these are held globally so they cannot be garbage
collected away).

> I tried epics.caget(); it created the CA connection and the connection
stayed open until the program exited.


Yes, when any channel is created, it is entered into the epics.ca._cache.
This is generally useful as it means doing a caget() again does not
establish a new connection, and may not even need to actually issue a
request (as most of the time the PVs are monitored).   That is keeping
"global state" about the connections to the individual channels.

>
> I tried pv = epics.PV() and then pv.disconnect(); the disconnect() method
closed all the event monitors on the pv, but did not close the connection.


I'm not sure why that did not happen.  That definitely clears the cache,
and tries to delete all references to all callbacks.  Perhaps it would be
useful to try garbage collecting after disconnecting the PV:
    import gc
    gc.collect()

I'm not sure why (or how) that is different from the "ca" level approach
below (except that it adds the magic needed to clear the cache and so not
crash).

>
> I tried epics.ca.create_channel() and then epics.ca.clear_channel(); the
clear_channel() indeed closed the CA connection.  But the problem with this
approach is that the program would crash if I call
epics.ca.create_channel() on the same pv again and try to get the state or
value from the returned channel ID, as the following.
>
> >>> chid = epics.ca.create_channel('xxx')
> >>> epics.ca.clear_channel(chid)
> 1
> >>> chid = epics.ca.create_channel('xxx')
> >>> epics.ca.state(chid)
> (crash!)

Ah, yes, I think you need to clear the cache to do this.

    epics.ca.clear_channel(chid)
    ctx =epics.ca.current_context()
    epics.ca._cache[ctx].pop(pvname)

You can probably guess that not many people seem to need to do this.  But,
it would certainly possible to add a convenience function (or perhaps even
an on-by-default argument to ca.clear_channel()).

> Finally, calling epics.ca.destroy_context() and epics.ca.create_context()
after epics.ca.clear_channel()
>  seems to allow a new connection to be created on the same pv, but that
would also wipe out all the existing
> channels I want to keep.

Yes, that does clear the cache, but the entire entry for the context.

Hope that helps,

--Matt Newville

Replies:
Re: Is There A Way to Explicitly Close CA Connections in PyEpics? Matt Newville
References:
Is There A Way to Explicitly Close CA Connections in PyEpics? Weiwei Lu
Re: Is There A Way to Explicitly Close CA Connections in PyEpics? Matt Newville

Navigate by Date:
Prev: RE: CARS:Modbus - function 06 (write single register) issue Nick Levchenko
Next: Re: MEDM Michael Westfall
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  <20162017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Is There A Way to Explicitly Close CA Connections in PyEpics? Matt Newville
Next: Re: Is There A Way to Explicitly Close CA Connections in PyEpics? Matt Newville
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  2013  2014  2015  <20162017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 23 Aug 2016 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·