Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TD-44] Syncing a new recurring task without task instances creates duplicates #46

Open
taskwarrior opened this issue Feb 11, 2018 · 19 comments
Labels
bug Something isn't working
Milestone

Comments

@taskwarrior
Copy link

Paul Beckingham on 2014-03-06T04:51:07Z says:

Given two pristine clients configured for sync, adding a recurring task to client1, then syncing before a report is run, will cause recurring task instances to be generated by both clients.

Reproduce:
[1] "task add Foo due:today recur:daily" on client 1
[2] "task sync" on client 1
[3] "task sync" on client 2
[4] "task list" on client 1
[5] "task list" on client 2
[6] "task sync" on client 1
[7] "task sync" on client 2
[8] "task sync" on client 1
[9] "task sync" on client 2

This creates duplicates and propagates them until exhaustion, yielding 4 tasks on each client, whereas 2 were expected. This can be found in the script:

taskd.git/demo/client/case7
@taskwarrior taskwarrior added this to the 1.1.0 milestone Feb 11, 2018
@taskwarrior taskwarrior added the bug Something isn't working label Feb 11, 2018
@taskwarrior
Copy link
Author

Migrated metadata:

Created: 2014-03-06T04:51:07Z
Modified: 2016-04-09T14:58:47Z

@taskwarrior
Copy link
Author

Renato Alves on 2014-04-23T14:10:28Z says:

Adding to the report, this problem also happens if tasks are generated in each client and synced later on.

Example:
[1] "task add Foo due:today recur:daily" on client 1
[2] "task list" on client 1
[2] "task sync" on client 1 (two tasks exist, parent and 1st child)
[3] "task sync" on client 2 (two tasks exist, parent and 1st child)
[5] "task 2 done" on client 1 (1st child complete)
[6] "task 2 done" on client 2 (1st child complete)
[7] 1 day passed
[8] "task list" on client 1 (2nd child generated)
[9] "task list" on client 2 (2nd child generated)
[10] "task sync" both clients (two 2nd children with same maskID will exist in each client)

Given that each client generates a different UUID, these will not be mapped to the same entity by taskd, resulting in regular task duplication.

As workaround I've been deleting the most recent 2nd child, but I don't know what side effects this might cause.
In the past I had one of the clients consistently fail on sync due to unresolved task parenthood. I've failed to reproduced this situation so far so I cannot associate it with the present bug report.

@taskwarrior
Copy link
Author

Renato Alves on 2014-10-13T15:23:02Z says:

As discussed with Paul, the solution to this problem is to merge tasks automatically based on information from "parent" and "imask/mask".

It was also decided that additional checks should be added to ensure consistency between "mask" and the changes in the current sync operation.
This should prevent strange mask transitions such as "deleted" -> "done" or "done" -> "waiting" without corresponding task changes.

@taskwarrior
Copy link
Author

Renato Alves on 2014-10-16T11:54:35Z says:

Scenario:

task add Recurring due:today recur:daily
1.  sync both clients
1.  mark task as complete on both clients (don't sync)
1.  wait for next day until new task is generated

Client1 will have:

Some-UUID imask=2 parent=parent-UUID Recurring

Client2 will have:

Other-UUID imask=2 parent=parent-UUID Recurring

Client1 syncs, taskd now contains:

Some-UUID imask=2 Recurring

Client2 syncs, taskd identifies duplicates based on imask, merges changes with existing task and responds with:

modify Other-UUID to Some-UUID

Is this an extension to the protocol? Should other clients (mirakel) be notified once implemented?

@taskwarrior
Copy link
Author

Tomas Babej on 2015-01-16T15:51:51Z says:

We cannot change UUID like that on the other client. External tools might refer to this task by that UUID. Instead, we should make UUID multivalued (only in this case), crazy as it sounds.

@taskwarrior
Copy link
Author

Tomas Babej on 2015-01-19T18:04:03Z says:

Note: I created a hook which can serve as a workaround for this issue (by blocking recurrence on all but one client).

https://github.com/tbabej/taskwarrior-block-recurrence-hook

@taskwarrior
Copy link
Author

Tomas Babej on 2015-01-25T21:47:12Z says:

The hook above does not work well. If you're on 2.4.1, you can use new setting:

{code}
recurrence=off
{code}

To disable the recurrence on one of the clients.

@taskwarrior
Copy link
Author

Johannes Wienke on 2016-01-08T07:34:06Z says:

Just for the record: There has also been some discussions in potentially this issue in TW-1625.

@taskwarrior
Copy link
Author

Paul Beckingham on 2016-04-09T14:58:47Z says:

Workaround:

If you have 3 clients syncing with Taskserver, make sure that 2 of the 3 clients have:

recurrence=off

Leaving the default recurrence=on for just one of the clients. This makes one client responsible for recurring task synthesis, thus avoiding the problem. It is best to choose the most active client for this role.

@PorcelainMouse
Copy link

Wow, that really didn't work.

I have had to avoid using one of my clients for a long time due to this issue. I haven't touched the task list in the past 6 months. I added "recurrence=off" to .taskrc on that client and synced. I got 54 new recurring tasks that I already completed on the other client.

@PorcelainMouse
Copy link

Okay, maybe those got created before "task sync". Same thing happened with another client. Ugh.

How can I be sure this will work? I guess I'll try next week and find out.

@PorcelainMouse
Copy link

Hmm, something is still wrong. Now, fully synced clients show different lists of tasks. One client still shows overdue tasks I deleted on another client. Is this right? Do I have to delete tasks on every client? Are deleted tasks not synced?

@PorcelainMouse
Copy link

Cool, I think my secondary clients are working as expected, now. I synced them, again, and didn't get any new recurring tasks. Thanks for the advice!

@corbolais
Copy link
Contributor

Is this workaround still the way to go? And will it be so for the rest of the days? I'd kinda like to announce a slight preferrence on the bright side of code: will there be a fix to correct this bug?

thanks

@devurandom
Copy link

Still an issue with taskwarrior 2.5.1 and taskd 1.1.0. I confirm that here the issue is also an integer / float mask index as pointed out in GothenburgBitFactory/taskwarrior#1649.

@rbuchberger
Copy link

rbuchberger commented May 25, 2019

I'm still having this issue as well. My planned workaround is to set up a "master" client on my taskd server, run it ~hourly with a crontab, and disable recurrence on all other clients. Will report back if it works well.

Maybe taskd should handle recurrence?

Update: This workaround seems to work fine.

@matt-snider
Copy link

@rbuchberger This seems like a good workaround. Is the crontab script running on the taskd server simply doing task sync or how are you triggering the generation of recurring tasks?

@rbuchberger
Copy link

rbuchberger commented Sep 26, 2019

@matt-snider My little script runs 3 steps -

`task sync` # Pull any newly created recurring tasks
`task`      # Generate recurring task instances
`task sync` # Push the new ones

You could eliminate one of the task syncs, but then you'll have to wait 2 runs for new recurring tasks to get picked up rather than 1.

One weird quirk I've noticed after using it for awhile is that when you create a new recurring task on another computer, it won't show as pending (meaning it won't be in any of your usual reports) until the next cron job. Tripped me up for a bit.

Another implementation might be to use a tool like entr to watch taskd's data files and run the job whenever they change? Or just run it more than hourly; they're fast, you could run them every minute if you wanted.

@matt-snider
Copy link

@rbuchberger Thanks that's a good straightforward solution! Now I see how my approach with the single task sync call would have missed tasks, or at least it would take a few runs before they were on all other devices.

I will keep my eye out for that quirk. So far haven't noticed it, but for now I'm just glad to be rid of all the duplicate recurring tasks.

That could also work. But I think the workaround you suggested makes sense, is simple, and gets the job done 😄 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

6 participants