Proxy objects and plugin classes
Proxy objects
All objects in ganga are derived from the
GangaObject superclass and have to provide some metadata (defined as static class variables).
Object metadata and schema properties
The metadata contains:
- a schema specifying their attributes/properties. Only those properties are correctly saved in the repository. A schema always has a version that has to be bumped if something in the schema is modified. The properties in the schema are of the type SimpleItem (containing primitive values like integers, strings, booleans, ...) or ComponentItem (containing class instances of a given category, see below).
- a name and category. The name is used as class name in the GPI (so the name given to the class itself is not exported to GPI!), and the category defines where instances of this class may be inserted into the job-object hierarchy (also in the repository). E.g., there are several possible backends the user can choose from; each of those is defined by a GangaObject with the category 'backends'.
- a list of methods to be exposed to GPI. These methods have to be defined in the class, of course; though, only the methods inserted into this list can be accessed later by the user.
- optionally, a list of prefs and/or advanced prefs for the GUI
An example of a typical metadata definition:
_schema = Schema(Version(1,2), {'nice' : SimpleItem(defvalue=None,typelist=None,doc='*NOT USED*', hidden=1),
'id' : SimpleItem(defvalue=-1,protected=1,copyable=0,doc='Process id.'),
'status' : SimpleItem(defvalue=None,typelist=None,protected=1,copyable=0,hidden=1,doc='*NOT USED*'),
'exitcode' : SimpleItem(defvalue=None,typelist=['int','type(None)'],protected=1,copyable=0,doc='Process exit code.'),
'workdir' : SimpleItem(defvalue='',protected=1,copyable=0,doc='Working directory.'),
'actualCE' : SimpleItem(defvalue='',protected=1,copyable=0,doc='Hostname where the job was submitted.'),
'wrapper_pid' : SimpleItem(defvalue=-1,protected=1,copyable=0,hidden=1,doc='(internal) process id of the execution wrapper'),
'nice' : SimpleItem(defvalue=0, doc='adjust process priority using nice -n command')
})
_category = 'backends'
_name = 'Local'
_GUIPrefs = [ { 'attribute' : 'nice', 'widget' : 'String' },
{ 'attribute' : 'id', 'widget' : 'Int' },
{ 'attribute' : 'status' , 'widget' : 'String' },
{ 'attribute' : 'exitcode', 'widget' : 'String' } ]
_GUIAdvancedPrefs = [ { 'attribute' : 'nice', 'widget' : 'String' },
{ 'attribute' : 'exitcode', 'widget' : 'String' } ]
Items in a schema
Any property declared in a schema can be a
SimpleItem,
ComponentItem or a
FileItem. As can be seen in the example, when constructing items, some flags (named
metaattributes) can be used to specify the desired behaviour. A short list of useful metaattributes:
Generic metaattributes
- transient : never stored on persistent media
- protected : not modifiable via GPI
- hidden : not visible in the GPI
- comparable: taken into account for equality checks
- sequence: an item is a sequence (algorithms traversing the component tree dive into sequences as well)
- strict_sequence: if not strict sequence then assignment of a single item will be automatically converted to a 1-element sequence, i.e. obj.x = v => obj.x = [v]
- defvalue : default value, if item is a sequence the defvalue must be a list. For ComponentItems this must be either None or a string with a name of the component in the same category
- copyable : if 0 then the property value will not be copied and the default value from schema will be set in the destination
- doc : a docstring
- checkset : a bound checkset method, restrict write access at the object level (for example job.status may not be modified directly in backend handlers, instead updateStatus() method should be used)
- visitable : if false then all algorithms based on the visitor patter will not accept this item [true]. This is needed in certain cases (such as job.master) to avoid infinite recursion (and loops)
- summary_print: An bound method name (string). Will be passed an attribute value and a verbosity_level. Should return a (Python parsable) string summarising the state of the value.
- summary_sequence_maxlen: An integer longer than which a sequence will be summerised when doing a summary print. If the value is -1, the sequence will never be summerised.
- category : category of the component ('applications','backends',...)
- pptional : if true then None may be used as a legal value of the item, [false]
- load_default: if true and defvalue is None then load default plugin, [true]
- getter : a bound getter method, this implies that the component does not have associated storage and cannot be neither set nor deleted [None]. getter implies: transient=1, protected=1, sequence=0, defvalue=None, load_default=0, optional=1, copyable=0
- proxy_get: a bound getter method for proxy decoration, allows to customize completely the creation of the proxy
Loading order / Ganga bootstrap
When launched, Ganga first loads and initializes its core plugins and classes, including Job,
GangaList, the interfaces for Backends, Applications, Splitters and Mergers, and the builtin Backend- and Application-plugins. Then, the runtime plugins enabled in the user's
.gangarc
are loaded. When implementing a new runtime Plugin, be sure to import all needed classes in its
__init__.py
!
Inheriting classes from GangaObject
To make your class visible in Ganga GPI you must inherit from
GangaObject. This is the common procedure for all handler classes like LSF or Gaudi.
If you want to further derive classes from your base class you must make sure that the _schema object is copied properly. Example:
class Gaudi(GangaObject):
_schema = Schema(...)
_name = 'Gaudi'
_category = 'application'
dv_schema = Gaudi._schema.inherit_copy()
#modify dv_schema at will
class DaVinci(Gaudi):
_schema = dv_schema
_name = 'DaVinci'
_category = 'application'
--
TimMuenchen - 10 Aug 2009