Modify

Opened 12 years ago

Closed 12 years ago

#10313 closed defect (fixed)

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

Reported by: falkb Owned by: Chris Nelson
Priority: high Component: TracJsGanttPlugin
Severity: critical Keywords:
Cc: Trac Release: 0.12

Description (last modified by Ryan J Ollos)

        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.

Attachments (3)

alap_finishtoday.png (4.3 KB) - added by falkb 12 years ago.
chart1-ticket10313.PNG (25.4 KB) - added by falkb 12 years ago.
query1-ticket10313.PNG (12.6 KB) - added by falkb 12 years ago.

Download all attachments as: .zip

Change History (20)

Changed 12 years ago by falkb

Attachment: alap_finishtoday.png added

comment:1 Changed 12 years ago by falkb

comment:2 Changed 12 years ago by Ryan J Ollos

Description: modified (diff)

comment:3 Changed 12 years ago by falkb

Severity: normalcritical

this issue mostly feeds the denier of this chart here

comment:4 Changed 12 years ago by Chris Nelson

Status: newassigned

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

comment:5 Changed 12 years ago by Chris Nelson

Priority: normalhigh

comment:6 Changed 12 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 12 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 12 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:

Changed 12 years ago by falkb

Attachment: chart1-ticket10313.PNG added

comment:9 Changed 12 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?

Changed 12 years ago by falkb

Attachment: query1-ticket10313.PNG added

comment:10 Changed 12 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 12 years ago by falkb

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

comment:12 Changed 12 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 12 years ago by Chris Nelson

Replying to ChrisNelson:

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 12 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 Changed 12 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 12 years ago by falkb

Replying to ChrisNelson:

it does make the

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

comment:17 Changed 12 years ago by falkb

Resolution: fixed
Status: assignedclosed

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain Chris Nelson.
The resolution will be deleted. Next status will be 'reopened'.

Add Comment


E-mail address and name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.