Inheritance¶
We have seen in the runtime tutorial how tasks can be grouped into families.
In this tutorial we will look at nested families, inheritance order and multiple inheritance.
Inheritance Hierarchy¶
Create a new suite by running the command:
rose tutorial inheritance-tutorial
cd ~/cylc-run/inheritance-tutorial
You will now have a suite.rc
file that defines two tasks each representing
a different aircraft, the Airbus A380 jumbo jet and the Robson R44 helicopter:
[scheduling]
[[dependencies]]
graph = a380 & r44
[runtime]
[[VEHICLE]]
init-script = echo 'Boarding'
pre-script = echo 'Departing'
post-script = echo 'Arriving'
[[AIR_VEHICLE]]
inherit = VEHICLE
[[[meta]]]
description = A vehicle which can fly.
[[AIRPLANE]]
inherit = AIR_VEHICLE
[[[meta]]]
description = An air vehicle with fixed wings.
[[[environment]]]
CAN_TAKE_OFF_VERTICALLY = false
[[HELICOPTER]]
inherit = AIR_VEHICLE
[[[meta]]]
description = An air vehicle with rotors.
[[[environment]]]
CAN_TAKE_OFF_VERTICALLY = true
[[a380]]
inherit = AIRPLANE
[[[meta]]]
title = Airbus A380 Jumbo-Jet.
[[r44]]
inherit = HELICOPTER
[[[meta]]]
title = Robson R44 Helicopter.
Note
The [meta]
section is a freeform section where we can define metadata
to be associated with a task, family or the suite itself.
This metadata should not be mistaken with Rose Configuration Metadata.
Reminder
By convention we write family names in upper case (with the exception of the
special root
family) and task names in lower case.
These two tasks sit at the bottom of an inheritance tree. The cylc graph
command has an option (-n
) for drawing such inheritance hierarchies:
cylc graph -n . &
Running this command will generate the following output:
Note
The root
family sits at the top of the inheritance tree as all
tasks/families automatically inherit it:
Cylc handles inheritance by starting with the root family and working down the inheritance tree applying each section in turn.
To see the resulting configuration for the a380
task use the
cylc get-config
command:
cylc get-config . --sparse -i "[runtime][a380]"
You should see some settings which have been inherited from the VEHICLE
and
AIRPLANE
families as well as a couple defined in the a380
task.
init-script = echo 'Boarding' # Inherited from VEHICLE
pre-script = echo 'Departing' # Inherited from VEHICLE
post-script = echo 'Arriving' # Inherited from VEHICLE
inherit = AIRPLANE # Defined in a380
[[[meta]]]
description = An air vehicle with fixed wings. # Inherited from AIR_VEHICLE - overwritten by AIRPLANE
title = Airbus A380 Jumbo-Jet. # Defined in a380
[[[environment]]]
CAN_TAKE_OFF_VERTICALLY = false # Inherited from AIRPLANE
Note that the description
setting is defined in the AIR_VEHICLE
family but is overwritten by the value specified in the AIRPLANE
family.
Multiple Inheritance¶
Next we want to add a vehicle called the V-22 Osprey to the suite. The V-22 is a cross between a plane and a helicopter - it has wings but can take-off and land vertically.
As the V-22 can be thought of as both a plane and a helicopter we want it to
inherit from both the AIRPLANE
and HELICOPTER
families. In Cylc we can
inherit from multiple families by separating their names with commas:
Add the following task to your suite.rc
file.
[[v22]]
inherit = AIRPLANE, HELICOPTER
[[[meta]]]
title = V-22 Osprey Military Aircraft.
Refresh your cylc graph
window or re-run the cylc graph
command.
The inheritance hierarchy should now look like this:
Inspect the configuration of the v22
task using the cylc get-config
command.
Hint
cylc get-config . --sparse -i "[runtime][v22]"
You should see that the CAN_TASK_OFF_VERTICALLY
environment variable has
been set to false
which isn’t right. This is because of the order in which
inheritance is applied.
Cylc handles multiple-inheritance by applying each family from right to left.
For the v22
task we specified inherit = AIRPLANE, HELICOPTER
so the
HELICOPTER
family will be applied first and the AIRPLANE
family after.
The inheritance order would be as follows:
root
VEHICLE
AIR_VEHICLE
HELICOPTER # sets "CAN_TAKE_OFF_VERTICALLY to "true"
AIRPLANE # sets "CAN_TAKE_OFF_VERTICALLY to "false"
v22
We could fix this problem by changing the order of inheritance:
inherit = HELICOPTER, AIRPLANE
Now the HELICOPTER
family is applied second so its values will override any
in the AIRPLANE
family.
root
VEHICLE
AIR_VEHICLE
AIRPLANE # sets "CAN_TAKE_OFF_VERTICALLY to "false"
HELICOPTER # sets "CAN_TAKE_OFF_VERTICALLY to "true"
v22
Inspect the configuration of the v22
task using cylc get-config
to
confirm this.
More Inheritance¶
We will now add some more families and tasks to the suite.
Engine Type¶
Next we will define four families to represent three different types of engine.
Each engine type should set an environment variable called FUEL
which we
will assign to the following values:
- Turbine - kerosene
- Internal Combustion - petrol
- Human - pizza
Add lines to the runtime
section to represent these four families.
Solution
[[ENGINE]]
[[TURBINE_ENGINE]]
inherit = ENGINE
[[[environment]]]
FUEL = kerosene
[[INTERNAL_COMBUSTION_ENGINE]]
inherit = ENGINE
[[[environment]]]
FUEL = petrol
[[HUMAN_ENGINE]]
inherit = ENGINE
[[[environment]]]
FUEL = pizza
We now need to make the three aircraft inherit from one of the three engines. The aircraft use the following types of engine:
- A380 - turbine
- R44 - internal combustion
- V22 - turbine
Modify the three tasks so that they inherit from the relevant engine families.
Solution
[[a380]]
inherit = AIRPLANE, TURBINE_ENGINE
[[[meta]]]
title = Airbus A380 Jumbo-Jet.
[[r44]]
inherit = HELICOPTER, INTERNAL_COMBUSTION_ENGINE
[[[meta]]]
title = Robson R44 Helicopter.
[[v22]]
inherit = AIRPLANE, HELICOPTER, TURBINE_ENGINE
[[[meta]]]
title = V-22 Ofsprey Military Aircraft.
Penny Farthing¶
Next we want to add a new type of vehicle, an old-fashioned bicycle called a penny farthing.
To do this we will need to add two new families, LAND_VEICHLE
and
BICYCLE
as well as a new task, penny_farthing
related in the
following manner:
Add lines to the runtime
section to represent the two new families and one
task outlined above.
Add a description ([meta]description
) to the LAND_VEHICLE
and
BICYCLE
families and a title ([meta]title
) to the penny_farthing
task.
Solution
[[LAND_VEHICLE]]
inherit = VEHICLE
[[[meta]]]
description = A vehicle which can travel over the ground.
[[BICYCLE]]
inherit = LAND_VEHICLE
[[[meta]]]
description = A small two-wheeled vehicle.
[[penny_farthing]]
inherit = BICYCLE, HUMAN_ENGINE
[[[meta]]]
title = An old-fashioned bicycle.
Using cylc get-config
to inspect the configuration of the penny_farthing
task we can see that it inherits settings from the VEHICLE
,
BICYCLE
and HUMAN_ENGINE
families.
inherit = BICYCLE, HUMAN_ENGINE
init-script = echo 'Boarding' # Inherited from VEHICLE
pre-script = echo 'Departing' # Inherited from VEHICLE
post-script = echo 'Arriving' # Inherited from VEHICLE
[[[environment]]]
FUEL = pizza # Inherited from HUMAN_ENGINE
[[[meta]]]
description = A small two-wheeled vehicle. # Inherited from LAND_VEHICLE - overwritten by BICYCLE
title = An old-fashioned bicycle. # Defined in penny_farthing
Hint
cylc get-config . --sparse -i "[runtime]penny_farthing"
Hovercraft¶
We will now add a hovercraft called the Hoverwork BHT130, better known to some as the Isle Of Wight Ferry.
Hovercraft can move over both land and water and in some respects can be thought of as flying vehicles.
Write new families and one new task to represent the above structure.
Add a description ([meta]description
) to the WATER_VEHICLE
and
HOVERCRAFT
families and a title ([meta]title
) to the bht130
task.
Solution
[[WATER_VEHICLE]]
inherit = VEHICLE
[[[meta]]]
description = A vehicle which can travel over water.
[[HOVERCRAFT]]
inherit = LAND_VEHICLE, AIR_VEHICLE, WATER_VEHICLE
[[[meta]]]
description = A vehicle which can travel over ground, water and ice.
[[bht130]]
inherit = HOVERCRAFT, INTERNAL_COMBUSTION_ENGINE
[[[meta]]]
title = Griffon Hoverwork BHT130 (Isle Of Whight Ferry).
Finished Suite¶
You should now have a suite with an inheritance hierarchy which looks like this: