Modify

Opened 2 years ago

Closed 2 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: ChrisNelson
Priority: high Component: TracJsGanttPlugin
Severity: critical Keywords:
Cc: Trac Release: 0.12

Description (last modified by rjollos)

        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 2 years ago.
chart1-ticket10313.PNG (25.4 KB) - added by falkb 2 years ago.
query1-ticket10313.PNG (12.6 KB) - added by falkb 2 years ago.

Download all attachments as: .zip

Change History (20)

Changed 2 years ago by falkb

comment:1 Changed 2 years ago by falkb


comment:2 Changed 2 years ago by rjollos

  • Description modified (diff)

comment:3 Changed 2 years ago by falkb

  • Severity changed from normal to critical

this issue mostly feeds the denier of this chart here

comment:4 Changed 2 years ago by ChrisNelson

  • Status changed from new to assigned

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

comment:5 Changed 2 years ago by ChrisNelson

  • Priority changed from normal to high

comment:6 Changed 2 years ago by ChrisNelson

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 2 years ago by ChrisNelson

(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 2 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 2 years ago by falkb

comment:9 Changed 2 years ago by ChrisNelson

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

comment:10 Changed 2 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 2 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: Changed 2 years ago by 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.

comment:13 in reply to: ↑ 12 Changed 2 years ago by ChrisNelson

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 2 years ago by ChrisNelson

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: Changed 2 years ago by ChrisNelson

(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 2 years ago by falkb

Replying to ChrisNelson:

it does make the

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

comment:17 Changed 2 years ago by falkb

  • Resolution set to fixed
  • Status changed from assigned to closed

Add Comment

Modify Ticket

Action
as closed .
The resolution will be deleted. Next status will be 'reopened'.
Author


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

 
Note: See TracTickets for help on using tickets.