+ """PERF protocol handler
+
+ The PERF protocol provides an interface for program interaction
+ with the server process. It allows limited remote interactions
+ with Python objects over a few defined interfaces.
+
+ All objects that wish to be available for interaction need to
+ implement a method named `pdm_protocols' which, when called with
+ no arguments, should return a list of strings, each indicating a
+ PERF interface that the object implements. For each such
+ interface, the object must implement additional methods as
+ described below.
+
+ A client can find PERF objects to interact with either by
+ specifying the name of such an object in an existing module, or by
+ using the `dir' interface, described below. Thus, to make a PERF
+ object available for clients, it needs only be bound to a global
+ variable in a module and implement the `pdm_protocols'
+ method. When requesting an object from a module, the module must
+ already be imported. PDM will not import new modules for clients;
+ rather, the daemon process needs to import all modules that
+ clients should be able to interact with. PDM itself always imports
+ the pdm.perf module, which contains a few basic PERF objects. See
+ its documentation for details.
+
+ The following interfaces are currently known to PERF.
+
+ * attr:
+ An object that implements the `attr' interface models an
+ attribute that can be read by clients. The attribute can be
+ anything, as long as its representation can be
+ pickled. Examples of attributes could be such things as the CPU
+ time consumed by the server process, or the number of active
+ connections to whatever clients the program serves. To
+ implement the `attr' interface, an object must implement
+ methods called `readattr' and `attrinfo'. `readattr' is called
+ with no arguments to read the current value of the attribute,
+ and `attrinfo' is called with no arguments to read a
+ description of the attribute. Both should be
+ idempotent. `readattr' can return any pickleable object, and
+ `attrinfo' should return either None to indicate that it has no
+ description, or an instance of the pdm.perf.attrinfo class.
+
+ * dir:
+ The `dir' interface models a directory of other PERF
+ objects. An object implementing it must implement methods
+ called `lookup' and `listdir'. `lookup' is called with a single
+ string argument that names an object, and should either return
+ another PERF object based on the name, or raise KeyError if it
+ does not recognize the name. `listdir' is called with no
+ arguments, and should return a list of known names that can be
+ used as argument to `lookup', but the list is not required to
+ be exhaustive and may also be empty.
+
+ * invoke:
+ The `invoke' interface allows a more arbitrary form of method
+ calls to objects implementing it. Such objects must implement a
+ method called `invoke', which is called with one positional
+ argument naming a method to be called (which it is free to
+ interpret however it wishes), and with any additional
+ positional and keyword arguments that the client wishes to pass
+ to it. Whatever `invoke' returns is pickled and sent back to
+ the client. In case the method name is not recognized, `invoke'
+ should raise an AttributeError.
+
+ * event:
+ The `event' interface allows PERF objects to notify clients of
+ events asynchronously. Objects implementing it must implement
+ methods called `subscribe' and `unsubscribe'. `subscribe' will
+ be called with a single argument, which is a callable of one
+ argument, which should be registered to be called when an event
+ pertaining to the `event' object in question occurs. The
+ `event' object should then call all such registered callables
+ with a single argument describing the event. The argument could
+ be any object that can be pickled, but should be an instance of
+ a subclass of the pdm.perf.event class. If `subscribe' is
+ called with a callback object that it has already registered,
+ it should raise a ValueError. `unsubscribe' is called with a
+ single argument, which is a previously registered callback
+ object, which should then be unregistered to that it is no
+ longer called when an event occurs. If the given callback
+ object is not, in fact, registered, a ValueError should be
+ raised.
+
+ The pdm.perf module contains a few convenience classes which
+ implements the interfaces, but PERF objects are not required to be
+ instances of them. Any object can implement a PERF interface, as
+ long as it does so as described above.
+
+ The pdm.cli.perfclient class is the client-side implementation.
+ """