end18 / psutil

Automatically exported from code.google.com/p/psutil
Other
0 stars 0 forks source link

Cached properties ignoring terminated processes and code refactoring #126

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
As per private discussion with Jay we realized that some properties are 
different than the rest of the API in that they don't raise NSP exception as 
they should and need fixing.

A part of the API correctly raises NSP if the process has gone away at some 
point.
This is true for all those methods retrieving information which is variable in 
time, such as all get_* methods and send_signal(), terminate() and kill():

>>> import psutil
>>> p = psutil.Process(1431)
>>> p.get_cpu_times()
cputimes(user=0.02, system=0.0)
>>> p.kill()
>>> p.get_cpu_times()
Traceback (most recent call last):
  File "test/test_psutil.py", line 803, in test_zombie_process
    p.get_cpu_times()
  File "/usr/local/lib/python2.6/dist-packages/psutil/__init__.py", line 291, in get_cpu_times
    return self._platform_impl.get_cpu_times()
  File "/usr/local/lib/python2.6/dist-packages/psutil/_pslinux.py", line 177, in wrapper
    raise NoSuchProcess(self.pid, self._process_name)
NoSuchProcess: process no longer exists (pid=1431)

Other properties returning process *static* information, if accessed *before* 
the process disappears on us, just don't.
This is true for pid, ppid, name, exe and cmdline Process properties, which are 
all supposed to remain unchangeg during the entire life of the process:

>>> import psutil
>>> p = psutil.Process(1431)
>>> p.name
'python'
>>> p.kill()
>>> p.name
'python'

This is due to the fact that once those process information are retrieved the 
first time, results get cached and the underlying code which actually fetch the 
information from the kernel is no longer executed.
This was obviously done for performance but we think it's better for integrity 
to have an API behaving equally everywhere at cost of a reasonably little 
overhead.

As part of this process the code is gonna change quite a bit, despite no 
actually brand-new code is likely to be written.
Considering that it's not possible to commit a unique patch for all platforms 
I'm going to create a branch so that the trunk doesn't get broken in the 
process.
I recommend not to commit anything against the trunk as long as the branch 
doesn't get merged back to avoid collisions etc.

Original issue reported on code.google.com by g.rodola on 29 Oct 2010 at 11:48

GoogleCodeExporter commented 9 years ago
Branch at:
https://psutil.googlecode.com/svn/branches/cache-refactoring

To use it from the local copy of the trunk just do:
svn switch https://psutil.googlecode.com/svn/branches/cache-refactoring

Original comment by g.rodola on 29 Oct 2010 at 11:56

GoogleCodeExporter commented 9 years ago
Linux code committed in r752.

Original comment by g.rodola on 30 Oct 2010 at 12:15

GoogleCodeExporter commented 9 years ago
FreeBSD code committed in r753.

Original comment by g.rodola on 30 Oct 2010 at 1:18

GoogleCodeExporter commented 9 years ago
Windows code committed in r755.
Still a couple of failures for zombie ppid and name properties but they're 
gonna get better soon.
Re-assigning to Jay for completion on OSX.

Original comment by g.rodola on 30 Oct 2010 at 3:02

GoogleCodeExporter commented 9 years ago
OS X committed in r757

Everything is passing except for test_zombie_process() which is not raising NSP 
on exe attribute. It seems like it's not raising NSP when we read the cmdline 
to figure out the exe, so it falls through and returns "" for exe, instead of 
raising NSP from the exe attribute.

Original comment by jlo...@gmail.com on 30 Oct 2010 at 3:39

GoogleCodeExporter commented 9 years ago

Original comment by jlo...@gmail.com on 30 Oct 2010 at 3:39

GoogleCodeExporter commented 9 years ago
I think you can do as follows, as I did on Windows:

    def get_process_exe(self):
        # no such thing as "exe" on OSX; it will maybe be determined
        # later from cmdline[0]
        if not pid_exists(self.pid):
            raise NoSuchProcess(self.pid, self._process_name)
        return ""

Original comment by g.rodola on 30 Oct 2010 at 5:12

GoogleCodeExporter commented 9 years ago
Merged branch changes back into trunk as r760 and deleted branch in r761.

Original comment by g.rodola on 30 Oct 2010 at 5:45

GoogleCodeExporter commented 9 years ago
Ok, this works... I also had to do the same for cmdline as well.. it appears 
the cmdline function does not raise NoSuchProcess when the process has gone 
away either. 

This works for now, but for the long term I would like to refactor the OS X 
commandline code (and hopefully fix Issue #83 at the same time. I will open a 
new issue to remind myself to refactor the code at a future date. 

Original comment by jlo...@gmail.com on 30 Oct 2010 at 5:51

GoogleCodeExporter commented 9 years ago
Fixed OS X in r762

Original comment by jlo...@gmail.com on 30 Oct 2010 at 5:53

GoogleCodeExporter commented 9 years ago

Original comment by jlo...@gmail.com on 30 Oct 2010 at 5:54

GoogleCodeExporter commented 9 years ago

Original comment by g.rodola on 13 Nov 2010 at 3:14

GoogleCodeExporter commented 9 years ago

Original comment by g.rodola on 9 Jun 2011 at 10:33

GoogleCodeExporter commented 9 years ago
[deleted comment]
GoogleCodeExporter commented 9 years ago
Updated csets after the SVN -> Mercurial migration:
r752 == revision ???
r753 == revision ???
r755 == revision ???
r757 == revision ???
r760 == revision 9eb8a9833278
r762 == revision 22a716a1d49f

Original comment by g.rodola on 2 Mar 2013 at 11:56