Opened 5 years ago

Closed 5 years ago

# schedule=alap: ticket finish date must default to milestone but not to today (if dependencies don't give a date)

Reported by: Owned by: falkb Chris Nelson high TracJsGanttPlugin critical 0.12

        def _schedule_task_alap(t):

...

# If we haven't scheduled this yet, do it now.
if t.get('calc_finish') == None:
# If there is a finish set, use it
if self.pm.isSet(t, 'finish'):
# Don't adjust for work week; use the explicit date.
finish = self.pm.parseFinish(t)
finish += timedelta(hours=options['hoursPerDay'])
finish = [finish, True]
# Otherwise, compute finish from dependencies.
else:
finish = _earliest_successor(t, _ancestor_finish(t))

==> WRONG!          # If dependencies don't give a date, default to
==> WRONG!          # today at close of business
if finish == None:
# Start at midnight today
==> ask milestone       finish = datetime.today().replace(hour=0,
minute=0,
second=0,
microsecond=0)


Please, could you tell me, how I change  finish = datetime.today()...  into something like  finish = milestone.datetime()... ?

At present, all tickets without dependencies and without set fields.start or fields.finish are scheduled to start in the past which is nonsense. ALAP means to me such tickets need at least to start with a finish on milestone date.

### comment:2 Changed 5 years ago by Ryan J Ollos

Description: modified (diff)

### comment:3 Changed 5 years ago by falkb

Severity: normal → critical

this issue mostly feeds the denier of this chart here

### comment:4 Changed 5 years ago by Chris Nelson

Status: new → assigned

I'll try to look at this this week. Thanks for your patience.

### comment:5 Changed 5 years ago by Chris Nelson

Priority: normal → high

### comment:6 Changed 5 years ago by Chris Nelson

I'm trying to reacquaint myself with this code (I've been away from it for a while and, as noted elsewhere, scheduling is complex). It seems to me that "earliest successor" should include the milestone so it's not clear to me why this isn't working already.

### comment:7 Changed 5 years ago by Chris Nelson

(In [12178]) Log scheduling in ALAP scheduler. Refs #10313.

Add logScheduling = 1 to the [TracPM] section of trac.ini to get output like:

INFO: ancestor finish for 244 is None
INFO: earliest successor for 244 is None
INFO: Defaulted finish for 244 to [datetime.datetime(2012, 10, 17, 0, 0), False]
INFO: Adjusted finish of 244 to end of day, [datetime.datetime(2012, 10, 16, 8, 0), False]
INFO: ancestor finish for 235 is [datetime.datetime(2012, 10, 16, 8, 0), False]
INFO: earliest successor for 235 is [datetime.datetime(2012, 10, 16, 8, 0), False]
INFO: ancestor finish for 232 is [datetime.datetime(2012, 10, 16, 8, 0), False]
INFO: ancestor finish for 246 is [datetime.datetime(2012, 10, 16, 8, 0), False]
INFO: Explicit finish for -1 is [datetime.datetime(2012, 9, 3, 8, 0), True]
INFO: earliest successor for 246 is [datetime.datetime(2012, 9, 3, 0, 0), True]
INFO: Adjusted finish of 246 to end of day, [datetime.datetime(2012, 8, 31, 8, 0), True]
INFO: ancestor finish for 236 is [datetime.datetime(2012, 10, 16, 8, 0), False]
INFO: earliest successor for 236 is [datetime.datetime(2012, 9, 3, 0, 0), True]
INFO: ancestor finish for 237 is [datetime.datetime(2012, 10, 16, 8, 0), False]
INFO: earliest successor for 237 is [datetime.datetime(2012, 9, 3, 0, 0), True]
INFO: Adjusted finish of 237 to end of day, [datetime.datetime(2012, 8, 31, 8, 0), True]
INFO: earliest successor for 232 is [datetime.datetime(2012, 8, 28, 0, 0), True]
INFO: Adjusted finish of 232 to end of day, [datetime.datetime(2012, 8, 27, 8, 0), True]
INFO: ancestor finish for 234 is [datetime.datetime(2012, 8, 27, 8, 0), True]
INFO: earliest successor for 234 is [datetime.datetime(2012, 8, 27, 8, 0), True]
INFO: ancestor finish for 233 is [datetime.datetime(2012, 8, 27, 8, 0), True]
INFO: earliest successor for 233 is [datetime.datetime(2012, 8, 23, 0, 0), True]
INFO: Adjusted finish of 233 to end of day, [datetime.datetime(2012, 8, 22, 8, 0), True]


which will trace the scheduling and help me find the problem.

### comment:8 Changed 5 years ago by falkb

[2012-10-17 10:51:21,045 p2788:t3236] tracpm.py:1041 INFO: ancestor finish for 2677 is None
[2012-10-17 10:51:21,045 p2788:t3236] tracpm.py:1041 INFO: earliest successor for 2677 is None
[2012-10-17 10:51:21,045 p2788:t3236] tracpm.py:1041 INFO: Defaulted finish for 2677 to [datetime.datetime(2012, 10, 18, 0, 0), False]
[2012-10-17 10:51:21,045 p2788:t3236] tracpm.py:1041 INFO: Adjusted finish of 2677 to end of day, [datetime.datetime(2012, 10, 17, 8, 0), False]
[2012-10-17 10:51:21,045 p2788:t3236] tracpm.py:1041 INFO: ancestor finish for 2679 is [datetime.datetime(2012, 10, 17, 8, 0), False]
[2012-10-17 10:51:21,045 p2788:t3236] tracpm.py:1041 INFO: earliest successor for 2679 is [datetime.datetime(2012, 10, 17, 8, 0), False]
[2012-10-17 10:51:21,061 p2788:t3236] tracpm.py:1041 INFO: ancestor finish for 2678 is [datetime.datetime(2012, 10, 17, 8, 0), False]
[2012-10-17 10:51:21,061 p2788:t3236] tracpm.py:1041 INFO: earliest successor for 2678 is [datetime.datetime(2012, 10, 12, 7, 30), False]


This one is an easy example. The milestone is at 24/Oct. The appropriate chart is:

### comment:9 Changed 5 years ago by Chris Nelson

Odd. Assuming 2677 is in the right milestone, it's earliest successor should be the milestone. I assume there is a due date in the milestone but not the ticket?

### comment:10 Changed 5 years ago by falkb

Its milestone ...42...-M3 is due 24/Oct. Note that I retouched the real milestone name with some dots.

Look here for the tickets schedule:

The chart macro call is  [[TracJSGanttChart(milestone=...4...- M3,logScheduling = 1,schedule=alap,resolution!=duplicate|invalid&summary=~AP03)]]

### comment:11 Changed 5 years ago by falkb

Plan-Start is the datetime of the ticket start, Plan-Ende is the due date of the ticket.

### comment:12 follow-up:  13 Changed 5 years ago by Chris Nelson

The problem seems to be that 2677 isn't getting getting the milestone date from it's earliest successor (the milestone). I'll try creating three tickets like yours and see what I see. Thanks for the detail.

### comment:13 in reply to:  12 Changed 5 years ago by Chris Nelson

The problem seems to be that 2677 isn't getting getting the milestone date from it's earliest successor (the milestone). I'll try creating three tickets like yours and see what I see. Thanks for the detail.

I see the problem here. That's a great first step... ;-)

### comment:14 Changed 5 years ago by Chris Nelson

The problem appears to be in:

                # Any ticket with this as a milestone and no
# successors has the milestone as a successor
if self.isCfg(['pred', 'succ']):
pred = []
for t in tickets:
if not t['children'] and \
t['milestone'] == row[0] and \
self.successors(t) == []:
if self.isField('succ'):
t[self.fields[self.sources['succ']]] = \
[ tid ]
else:
t['succ'] = [ tid ]


Because 2677 has children, the milestone is not added as a successor. I don't know why that test is there. There is code -- on one branch or another -- dependencies copied up and down the family tree before scheduling so this may be a guard associated with that but I don't see the reason for it.

### comment:15 follow-up:  16 Changed 5 years ago by Chris Nelson

(In [12213]) Make group tickets depend on their milestones. Refs #10313.

This is an imperfect fix. I don't like that the chart shows an explicit dependency between the group and the milestone. But it does make the schedule correct.

I'd like to undo this and add code in the area where I propagate dependencies down from parents to children to make groups depend on their milestone only in the augmented graph within the scheduler. That would make the schedule correct and eliminate the stray dependency line on the chart. But that's more work than I can do now and this is better.

### comment:16 in reply to:  15 Changed 5 years ago by falkb

it does make the

Yezzzzzzz, it works! Thanks a lot. Kudos++

### comment:17 Changed 5 years ago by falkb

Resolution: → fixed assigned → closed

### Modify Ticket

Change Properties