[patch] adding propagation of task priority through followers

4 views
Skip to first unread message

Grégoire Barbier

unread,
Aug 7, 2009, 4:16:43 AM8/7/09
to taskjug...@googlegroups.com
See the patch comment for details.

By the way, I think that the new feature should be enabled by default,
since it's more intuitive to propagate priorities and does not break any
existing contract since it only propagates priorities to tasks that have
no explicit priority specification.

Do you agree with that?

In the patch it's disabled by default, but I can write another small
patch to change that.

--
Gregoire Barbier :: g (at) g76r (dot) eu :: +33 6 21 35 73 49

0021-Adding-propagation-of-task-priority-through-follower.patch

Chris Schlaeger

unread,
Aug 20, 2009, 3:51:14 PM8/20/09
to taskjug...@googlegroups.com
Hi Gregoire,

I've though about this feature quite a bit, but I don't think we
should go that route. Tasks that are on multiple dependency paths are
not handled in a deterministic way. Whichever dependency paths get
propagated first, gets to set the priority.

You also have very unexpected behavior if the user specifies 'priority
500' in a top level task. This gets basically ignored whereas
'priority 501' would have a different effect.

I guess you have a good reason, not to put all your chain task as sub
tasks of a common ancestor? Yves has made a nice proposal to simplify
the creation of chained sub-tasks.

I think that inheritance along dependency paths creates too many
headaches and is too confusing for most users.

Chris

Grégoire Barbier

unread,
Aug 20, 2009, 6:14:37 PM8/20/09
to taskjug...@googlegroups.com
Chris Schlaeger a écrit :

> Hi Gregoire,
>
> I've though about this feature quite a bit, but I don't think we
> should go that route. Tasks that are on multiple dependency paths are
> not handled in a deterministic way. Whichever dependency paths get
> propagated first, gets to set the priority.
>

Interesting, I though I managed to fix that issue by browsing all the
dependency paths and by using the max priority of all paths. So should I
test again.

> You also have very unexpected behavior if the user specifies 'priority
> 500' in a top level task. This gets basically ignored whereas
> 'priority 501' would have a different effect.
>

"Very unexpected behavior", I like that new name for bugs. ;-)
I need to look at that too.

> I guess you have a good reason, not to put all your chain task as sub
> tasks of a common ancestor?

Well, there are severeal reasons, ranking from rather bad to rather
good, for me not to put all chain tasks under a common ancestor:
- I very often use a separate toplevel subtask to get milestones apart
from real tasks, because it make it easier for me to have the same Gantt
diagram read by a wider audience (those who only look at milestones and
those who actually work on the project).
- The real world case that convincted me to add this feature was complex
enough to have several objectives inside same sub-sub-sub-task, and
adding some other intermediary subtasks was only one more burden. Of
course priorities were often changing.
- I, and my coworkers, find more intuitive to put priorities on
objectives rather than on super-super-super-containers. I don't expect
everyone to agree with me on that.

However I agree that using a common ancestor can help make a bunch of
task share the same priority...

> Yves has made a nice proposal to simplify
> the creation of chained sub-tasks.
>

Would you mind forwarding me this nice proposal please?

> I think that inheritance along dependency paths creates too many
> headaches and is too confusing for most users.
>

Scheduling projects by typing pseudo code rather than clicking all over
a window is confusing for many users too. ;-)
But I agree that most users would neither understand this feature
straighforward, nor really need it.

> Chris
>

I think I need to reconsider the patch, looking at the bugs you spotted
and at Jean-Yves' proposal, if you let me know about it.
Thank you for having taken time to review it.

Chris Schlaeger

unread,
Aug 21, 2009, 5:51:06 AM8/21/09
to taskjug...@googlegroups.com
Hi Gregoire,

> Interesting, I though I managed to fix that issue by browsing all the
> dependency paths and by using the max priority of all paths. So should I
> test again.

I have to admit, that I did not test your code. I just figured that
from reading the patch. I can imagine valid scenarios where you want
to de-prioritize a whole path. As soon as such a path is crossed by a
higher priority path, the tail of the low-prio path gets maxed as
well.

> Well, there are severeal reasons, ranking from rather bad to rather
> good, for me not to put all chain tasks under a common ancestor:
> - I very often use a separate toplevel subtask to get milestones apart
> from real tasks, because it make it easier for me to have the same Gantt
> diagram read by a wider audience (those who only look at milestones and
> those who actually work on the project).

Priorities only matter for tasks with resource allocations. The
priority of a milestone is irrelevant for the scheduling result.
Putting milestones under a differnt top-level task should be no
problem here.

> - The real world case that convincted me to add this feature was complex
> enough to have several objectives inside same sub-sub-sub-task, and
> adding some other intermediary subtasks was only one more burden. Of
> course priorities were often changing.

How about using macros like 'macro objective1 [ priority 800 ]' and
then put those macros in the tasks serving the same objective. It's
probably a bit more work than your proposal, but it's not a
perpendicular concept to the attribute inheritance.

> - I, and my coworkers, find more intuitive to put priorities on
> objectives rather than on super-super-super-containers. I don't expect
> everyone to agree with me on that.

Yeah, I agree with that. But usually the tasks of a particular
objective is found in a small number of sub-task-trees. The above
macro concept works good enough for me in those cases.

> Would you mind forwarding me this nice proposal please?

Sure. It's not fully baked yet, but it looks like this IIRC. Yves,
please chime in if I'm misrepresenting it.

task foo "Foo" {
task bar "bar"
chain on
task bar1 "Bar1"
task bar2 "Bar2"
task bar3 "Bar3"
chain off
task foobar
}

This automatically generates a 'depends !bar1' in foo.bar2 and
'depends !bar2' in foo.bar3. Obviously, this only pays off if you have
more than 3 chained tasks, but this seems to be a common situation.

> Scheduling projects by typing pseudo code rather than clicking all over
> a window is confusing for many users too. ;-)
> But I agree that most users would neither understand this feature
> straighforward, nor really need it.

Putting your project in a textfile is not something for every "project
manager". But not every project manager is a programmer that enjoys
the obfuscation possibilities of Perl either. So, I'd like to keep the
TJ syntax expressive, but simple.


> I think I need to reconsider the patch, looking at the bugs you spotted
> and at Jean-Yves' proposal, if you let me know about it.
> Thank you for having taken time to review it.

I'm somewhat afraid that such a construct creates corner cases with
unexpected behaviour. You can have another go at it, but I really want
to be sure we are not opening a can of worms here.

Chris

Aaron Brooks

unread,
Aug 21, 2009, 1:00:05 PM8/21/09
to TaskJuggler Development
Chris,

I hope this isn't too assertive having just started using
TaskJugglerIII (and loving it) but...

Example #1:

task foo "Foo" {
task bar "bar"
chain on
task bar1 "Bar1"
task bar2 "Bar2"
task bar3 "Bar3"
chain off
task foobar
}

seems like it could be clearer if it were:

Example #2:

task foo "Foo" {
task bar "bar"
taskchain {
task bar1 "Bar1" {
task baz1 "Baz1"
task baz2 "Baz2"
task baz3 "Baz3"
}
task bar2 "Bar2"
task bar3 "Bar3"
}
task foobar
}

In example #1 it's not clear if sub-tasks will be chained. In example
#2, not only is it clearer which tasks are effected (via indent) but
it allows you to express if the chaining is only at the specified
level or if the chaining applies to the full depth via a parameter:

Example #3:

task foo "Foo" {
task bar "bar"
taskchain deep {
task bar1 "Bar1" {
task baz1 "Baz1"
task baz2 "Baz2"
task baz3 "Baz3"
}
task bar2 "Bar2"
task bar3 "Bar3"
}
task foobar
}

The "deep" parameter to taskchain asserts that all sub-tasks should
also be chained in order. If the user wants a mix of chained and
unchained tasks they can use explicit single-level task chaining as
shown in example #2. Perhaps the implicit (non-recursive) default
parameter could be "shallow". BTW, I'm not strongly defending these
names, they're just what seemed reasonable after a few minutes of
thought. I wouldn't be surprised if one could do better.

Personally, I am a big fan of syntactical structures over stateful
setting and clearing of flags. The visual nesting and assistance from
editors (folding, brace matching, etc.) make this much more clear.

Any thoughts?

-Aaron

Chris Schlaeger

unread,
Aug 23, 2009, 11:51:38 AM8/23/09
to taskjug...@googlegroups.com
Aaron,

flags that control the parser operation are indeed a bad ingredient
for a computer language. Creating a syntactical block with 'taskchain
{ ... }' is definitely more intuitive syntax. It does have some
drawbacks though.

1. A foo { .. } construct in TJ syntax is either a property or
attribute. 'taskchain' would be neither of these.

2. It's more complicated to implement than the 'chain on/off' solution.

None of this is a showstopper and may even be worth it to avoid the
ugly flag switching. We'll chew on it a bit more.

Thanks for you feedback!
Chris

Grégoire Barbier

unread,
Sep 26, 2009, 6:27:02 AM9/26/09
to taskjug...@googlegroups.com
After a while thinking about it, I agree to withdraw my patch for
propagating task priority through followers.
I still think that it's an interesting way to think a project, but I
agree that it's inconsistent with too much thing in TJ and not so easy
to understand for the user.
Reply all
Reply to author
Forward
0 new messages