I should explain how I think the solution 1 task/x backend would work at the architecture level. I'll need a lot of attention, sorry :)
Let's start from the bottom: How is a backend structured. I'm talking about r/w backends here. Read only are simpler and import and export are even simpler. A backend will have a set of attached tags (tags for which the backend is entitled to store the task. the "all-tasks" is a special kind of tag here, so that case is covered) A backend will receive from GTG the list of tasks (I'll call those gtg_tasks) it should worry about. (This information is passed via the Backend.sync_function explained later). Each of these gtg_tasks has its own id and modification time, and that's all that matters to us. We don't know we're inside GTG, we don't know what a Datastore is, etc... A backend will fetch from its remote source of tasks a set of remote_tasks, each with their own id (which we cannot change) and modification time. So far it should be clear: a backend has two sets of tasks to match. Now, I'm interested in how to create a relationship between those sets, in order to discover which tasks are really the same task stored in two different forms (one on the backend, one inside GTG). We have two cases: i) First (sync) run ii) Later run On first run (i), things are easy: GTG_tasks and Remote_tasks are two sets without intersection, in the sense that the GTG_tasks have never been stored in the backend and vice versa. Therefore, we simply create a GTG_task for every Remote_tasks and vice versa. *you can skip this part* In reality, a previous attempt to sync may have happened, so instead of blindly creating copies for each task, in the RTM plugin I tried to match tasks with the same title before, so that we avoid duplicates. That works pretty well, apparently. *Now you read again* In order to remember the relationships that intercur between GTG_tasks and Remote_tasks, a backend will maintain a list of sync_memes, of this form: class sync_meme: remote_id gtg_id last_synced_modification_time_for_remote last_synced_modification_time_for_gtg every sync_meme ties a remote_task to a gtg_task (via the remote_id and gtg_id fields). On the first run, after creating the counterpart for each task, the backend records the modification time for both tasks (in the last_synced_modification_time_for_remote and last_synced_modification_time_for_gtg fields). This list of sync_meme is saved by the backend when the backend is shut down, and restored on initialization. It constitutes its memory of which tasks are linked. Now, let's restart GTG and analyze a later run (ii). The backend will have again two sets of tasks (remote_tasks and gtg_tasks), and he has to find out what has changed To do so, first he checks the current gtg_task ids with the ones stored in the sync_memes. Ids which are not present in the sync_memes are the new tasks in GTG, while ids which have disappeared will be tasks which have been removed from GTG. The backend will add a new task in the Remote_tasks for each new GTG task (and create a proper sync_meme) and **the backend will remove the corresponding remote task for each removed GTG task**. What I'm saying here is that once a task is removed, we don't care if it has been updated in the remote_tasks after the removal in GTG. It has been removed, so we remove it. This works perfectly well in the RTM plugin, and it simplifies things a lot. We do the same process for the remote_tasks (so, we find out the new and removed tasks, and we act as before). Now, we take all the task which have not been parts of the previous treatments. These tasks are the ones for which the relationship described in the sync_meme still stands. For every couple of tasks, we check the gtg_task modification time with the one stored in the sync_meme, and we do the same for the remote_task. If the modification times are equal or older than the sync_meme's stored ones, we do nothing (neither task has changed). If the modification time of just one of those tasks is sooner than the one stored in the sync_meme, that task has been modified, so we copy that task over the other. If the modification time of both tasks are sooner than the stored ones, we confront them and the newer gets to be copied over the other. This is, basically, how the RTM plugin currently operates. This process of syncing is in polling, so every once in a while a sync gets started. The user may optionally force it, via a nice button that he can smash at will. Now that you know how backends work in my idea, let's proceed up to our second part of the "journey", this time inside GTG. Let's start GTG again. Backends are somehow initialized (we don't care about that) and passed to the Datastore. The Datastore knows only two things about each backend: A) a unique id B) tags that are attached to the backend The Datastore main function is to come into action when on of these three events occur: 1)a task is created 2) a task is deleted 3) task's tags change When a task is created (1), the Datastore finds out which backends should store that task (based on the attached tags B) and creates a relationship between the task and the backend. This relationship is nothing more that a Backend.sync_function, that the task should call when it is modified. Every backend that matches the requirements will provide its sync_function to the task. Therefore, the task maintains a list of sync_functions, each of which have to be called when changes occur (more on this later, as its critical - bear with me). When a task is deleted (2), it is simply deleted from all backends. The backends will then propagate the deletion to the remote services. When a task's tags change, the task is removed from all the backends which do not have the correct tags to be entitled to store that anymore, and it's added to the backends which now fulfill the requirements. Now, suppose the user changes one task. The task calls all its sync_functions to notify the change. The representation of the gtg_task in the backend will be updated, along with its modification time. If the task modification time is newer that the one stored in the backend, the task will be synced remotely on the next sync. What happens if the backend stumbles in a remote_task which is newer than the gtg_task? Via the Requester, he checks that the GTG task is really older (double checking, just to be sure - it's not really needed) and it updates that, copying *the remote_task modification time to the task modification time*. The task will then call a sync, so that the change is propagated on other backends. I hope I have been clear. For the user case you'll have to wait I get a good night&morning rest :). Luca On Sat, May 22, 2010 at 03:04:34PM -0700, Bryce Harrington wrote: > > Usercase: > > Sandy has her GTG list. > > - eat pizza > > - buy pizza > > - something else > > Sandy keeps her shopping list on her phone. Therefore, before going to the > > supermarket, she tags buy pizza @RTM. > > Now, RTM does not support subtasks. What happen to "something else"? > > Thought of a few more launchpad use case ideas after sending the last email... > These really don't add much to the discussion, and are mostly predicated > on a read-write launchpad backend, but thought I'd throw them out to > help stimulate thought. > > Btw, I'm not saying we *should* do these things, only that if such > things *could* be done in some fashion with gtg. > > > 0. For all gtg bugs in status 'New', Bob creates individual tasks to > review and triage them. For each task, he loads the bug in firefox to > look at and work on, then marks it to status Confirmed in launchpad, and > closes the task in gtg. > > 1. Arthur retrieves a listing of all unassigned confirmed bugs, and > browses them, selecting subset to add to his task list. Launchpad is > then updated to mark those bugs as assigned to him. > > 2. Arthur imports 42 assigned launchpad bug reports. He decides to > focus on 2 this week starting tomorrow. He selects the other 40 and set > their start date to next week. > > 3. The next day, the 2 tasks/bugs become started and appear in Arthur's > WorkView. Launchpad is automatically updated to put the bugs into 'In > Progress' status. > > 4. For the first bug, Arthur decides to wait on working on it until > after he returns from a developer conference, so reschedules it for 3 > weeks. Launchpad is automatically updated to put the bug status back to > 'Triaged'. > > 5. For the second bug, Arthur notices that the reporter did not test > the correct version of the code. He adds a task for a triager > (e.g. Bob) to walk the reporter through the process of doing this > testing. This task is published to launchpad so any bug triager using > gtg can spot it and assign it to themselves. > > Bryce > > >
signature.asc
Description: Digital signature
_______________________________________________ Mailing list: https://launchpad.net/~gtg-contributors Post to : [email protected] Unsubscribe : https://launchpad.net/~gtg-contributors More help : https://help.launchpad.net/ListHelp

