P4DTI issue job000042

TitleRapid changes in the DT cause conflicts
Assigned userGareth Rees
DescriptionThe replicator thinks there's a conflict if a DT issue is rapidly changed more than once. It replicates the issue to the job, then wakes up and replicates it back (see job job000033), but by now it's changed again in the DT, so the replicator believes there's a conflict.
Currently (versions 0.4, 0.5, 1.0) there is a "defect tracker wins" policy by default, so this will not stop replication, but it will send annoying e-mails reporting conflicts where there are none, and thus increase the burden of the system on its users.
AnalysisThis has the same cause as job000016, job000086 and job000133. GDR 2000-12-06.
During the alpha testing, replication didn't go ahead when we closed a job. The user didn't get an e-mail. Why not? Was there a conflict? Could we be updating things too often so that it thinks there's a conflict when there's none? Could this be a fallout from an incorrect hack [GDR] made today?
The user was working too fast for the replicator. The replicator replicated the issue (in state new), then the user assigned the issue. The replicator woke up and saw that the issue had changed (because the user had changed it) and that the job had changed (because it had just replicated it and because it can't rely on the P4DTI-user field). This was a conflict. So I think this will be solved when we can accurately tell who edited the job in Perforce.
See also <http://www.ravenbrook.com/project/p4dt.../2001-02-22/version-1.0-support/#job-42>.

GDR 2001-06-19: This defect is present in P4D/NTX86/2001.1beta/22346.
How foundmanual_test
Evidence<http://www.ravenbrook.com/project/p4dti/doc/2000-11-03/quokka-alpha-test/> item 5
Observed in0.3.2
Test procedure<http://www.ravenbrook.com/project/p4dti/master/test/test_p4dti.py>, section 22
Created byRichard Brooksby
Created on2000-11-21 15:09:39
Last modified byGareth Rees
Last modified on2002-01-28 18:18:39
History2000-11-21 RB Created from sources (see evidence).
2000-12-04 RB Improved title and description text for end users.
2000-12-06 GDR Added analysis about sharing cause with other jobs.
2001-02-27 NB Edited description to reflect more recent versions.
2001-06-19 GDR Added analysis for Perforce 2001.1 beta.

Advice for all releases.

Symptom. The owner of a job receives an automatically generated e-mail message from the replicator looking like this:

Defect tracker issue 'BUG12345' and Perforce job 'BUG12345' have both changed since the last time the replicator polled the databases. The replicator's conflict resolution policy decided to overwrite the job with the issue.

The replicator has therefore overwritten Perforce job 'BUG12345' with defect tracker issue 'BUG12345'. See section 2.2 of the P4DTI User Guide for more information.

Cause 1 and solution. This e-mail can be caused by users simultaneously changing a defect tracking issue and the corresponding Perforce job, as described in section 2.2 of the P4DTI User's Guide. This is correct behaviour. In this case the user who changed the job should check to see if their changes have been lost by the overwrite. If so, they should edit the job again and make their changes again. Their changes to the job are included in the e-mail, so nothing has been lost.

Cause 2 and workaround. If someone makes two changes to an issue in the defect tracker in quick succession, the first change may be replicated successfully to Perforce. But when the replicator next polls the servers, it sees that the issue has changed again, but so has the corresponding job (it sees the change that it made itself on the previous replication). So it thinks both have changed and it overwrites the job with the issue. No harm is done by this feature of the P4DTI; it's just annoying to be sent e-mail needlessly. Users should just ignore these e-mails.

The underlying cause is that Perforce doesn't update the "always" fields in a job when someone affects that job by making or deleting a fix. This means that the replicator can't accurately tell who last changed a job, and so it has to consider changes that it made on previous replications as being candidates for replication. This is Perforce job 4308.


Change Effect Date User Description
26176 closed 2002-01-28 20:50:48 Gareth Rees Don't replicate changes in Perforce that we made in the previous poll.
Perforce interface records server changelevel.
In Perforce 2002.1, use the P4DTI-user field as an accurate guide as to who last edited the job.
5388 open 2000-12-04 18:41:38 Gareth Rees Removing resolver role from the integration:

Tidied up the replication and mailing methods to make this part of the replicator clearer. Changed replicate_issue_to_job() to replicate_issue_dt_to_p4() and replicate_job_to_issue() to replicate_issue_p4_to_dt() for consistency with other method names. Added new methods overwrite_issue_dt_to_p4() and overwrite_issue_p4_to_dt(), which are wrappers around the above methods that also e-mail the affected parties. In order to be able to e-mail the owner of a job, added the replicator method user_email_address for getting a Perforce user's e-mail address and the replicator configuration parameter job-owner-field that names the owner field in a job (the automatic configuration generator specifies 'Owner' for this). Removed the mail_administrator method() (use mail instead), and improved the mail() method. Improved many log entries by using issue.readable_name instead of issue.id. Re-organized and documented the replicate() function. It's no less complicated than it was before, but I think it's easier to understand. Functions like replicate() and replicate_issue_p4_to_dt() no longer return a meaningful error code. They either return or throw an exception.

Changed conflict_policy so that it always returns 'dt'. This is the key change that removes the resolver's role.

Changed the handling of errors to support the change in the conflict policy. There's now no need for conflict_error, so this is gone. The reverting of jobs to the corresponding issue is handled by the revert_issue_dt_to_p4() method: this ensures that it gets called in the correct place only (that is, normal replication from Perforce to the defect tracker has failed). The replicate_many() method no longer does any handling of errors. All other errors are caught by the run() method so that the replicator can keep on going, except AssertionError and KeyboardInterrupt, both of which stop the replicator.