| 2071 | return super().__or__(other) |
| 2072 | |
| 2073 | def freeze(self, _id=None, group_id=None, chord=None, |
| 2074 | root_id=None, parent_id=None, group_index=None): |
| 2075 | # pylint: disable=redefined-outer-name |
| 2076 | # XXX chord is also a class in outer scope. |
| 2077 | if not isinstance(self.tasks, group): |
| 2078 | self.tasks = group(self.tasks, app=self.app) |
| 2079 | # first freeze all tasks in the header |
| 2080 | header_result = self.tasks.freeze( |
| 2081 | parent_id=parent_id, root_id=root_id, chord=self.body) |
| 2082 | self.id = self.tasks.id |
| 2083 | # secondly freeze all tasks in the body: those that should be called after the header |
| 2084 | |
| 2085 | body_result = None |
| 2086 | if self.body: |
| 2087 | body_result = self.body.freeze( |
| 2088 | _id, root_id=root_id, chord=chord, group_id=group_id, |
| 2089 | group_index=group_index) |
| 2090 | # we need to link the body result back to the group result, |
| 2091 | # but the body may actually be a chain, |
| 2092 | # so find the first result without a parent |
| 2093 | node = body_result |
| 2094 | seen = set() |
| 2095 | while node: |
| 2096 | if node.id in seen: |
| 2097 | raise RuntimeError('Recursive result parents') |
| 2098 | seen.add(node.id) |
| 2099 | if node.parent is None: |
| 2100 | node.parent = header_result |
| 2101 | break |
| 2102 | node = node.parent |
| 2103 | |
| 2104 | return body_result |
| 2105 | |
| 2106 | def stamp(self, visitor=None, append_stamps=False, **headers): |
| 2107 | tasks = self.tasks |