| | 1 | = Syncing = |
| | 2 | |
| | 3 | == Scenarios == |
| | 4 | |
| | 5 | * 1-way: On setup, Server A's packages are copied to Server B. On sync, changes to packages on Server A are transferred to Server B. |
| | 6 | |
| | 7 | * 2-way: On setup, packages from each server is copied to the other. On sync, changes on each are transferred to the other. |
| | 8 | |
| | 9 | We will focus now on 1-way. |
| | 10 | |
| | 11 | == Requirements == |
| | 12 | |
| | 13 | Merging of changes from both machines. If there is a conflict then it is logged and a result is chosen. |
| | 14 | |
| | 15 | == Use cases == |
| | 16 | |
| | 17 | * First sync - all packages and revisions are copied from Server A to Server B. |
| | 18 | |
| | 19 | * Subsequent sync after package changes on A and/or B. |
| | 20 | |
| | 21 | * Sync after package purged on A. (Package also purged on B.) |
| | 22 | |
| | 23 | * Sync after package purged on B. (Package not recreated on B.) |
| | 24 | |
| | 25 | * Sync between CKAN instances of different versions of ckan & vdm. |
| | 26 | |
| | 27 | * Server B syncs at different times from Server C. |
| | 28 | |
| | 29 | * Package/Tag/Group name on Server A clashes with an existing one on Server B. Log all of them. Merge tag and group. Not sure about package. |
| | 30 | |
| | 31 | * Use of Server A and Server B continues undisturbed during sync. |
| | 32 | |
| | 33 | * Objects on Server A with restricted authz are by default editable on Server B. |
| | 34 | |
| | 35 | == Issues == |
| | 36 | |
| | 37 | * Unversioned objects - make versioned? User, Group, Authz, Rating. |
| | 38 | |
| | 39 | * How to test system. |
| | 40 | |
| | 41 | * Clashes of package names. |
| | 42 | |
| | 43 | == Operation == |
| | 44 | |
| | 45 | === First sync - 10am === |
| | 46 | |
| | 47 | Server B asks "Give me all your revisions and unrevisioned objects." |
| | 48 | |
| | 49 | Server A replies "Rev1 and associated revisions Pkg1Rev1, Pkg2Rev1, !PkgTagRev1, !PkgResource1; Rev2 with Pkg1Rev2; Tag1; User1; !PackageGroup1; Group1; ratings" |
| | 50 | |
| | 51 | Server B creates Rev1, Pkg1Rev1, Pkg2Rev1, Pkg1Rev2, Pkg1, Pkg2, !PkgTagRev1, !PkgResource1, Tag1, User1, Auth, !PackageGroup1, Group1. UUIDs are the same as Server A. |
| | 52 | |
| | 53 | Server B updates search vectors for Pkg1 and Pkg2. |
| | 54 | |
| | 55 | Server records the time of the sync - 10am. |
| | 56 | |
| | 57 | === Meanwhile - 10.20am === |
| | 58 | |
| | 59 | On Server A, user updates Pkg1 twice, creating Rev2/Pkg1Rev3 and Rev3/Pkg1Rev4PkgTagRev2. User1 updates his name. |
| | 60 | |
| | 61 | === Meanwhile - 10.40am === |
| | 62 | |
| | 63 | On Server B, user updates Pkg1 once, creating Pkg1Rev5. |
| | 64 | |
| | 65 | === Sesequent sync === |
| | 66 | |
| | 67 | Server B asks "Give me revisions and diffs since 10am." |
| | 68 | |
| | 69 | Server A replies Rev2/Pkg1Rev3, Rev3/Pkg1Rev4 and gives diff of Pkg1Rev2 -> Pkg1Rev4 |
| | 70 | |
| | 71 | Server B looks at its own revisions since 10am and sees Pkg1 now has two heads. It calculates diff of Pkg1Rev2 -> Pkg1Rev5. |
| | 72 | |
| | 73 | Server B takes Pkg1Rev2 and applies the two diffs in the order of priority, logging any conflicts, calling the result Pkg1Rev6. |
| | 74 | |
| | 75 | == Tickets == |
| | 76 | |
| | 77 | * Repository method 'all_revs_since'. It returns all revisions since a time/revision (or since the beginning). |
| | 78 | |
| | 79 | * Object method 'diff'. It returns a Diff object which is the diff of two !ObjectResources. Already exists for Package, but need for !PackageTag, !PackageExtra |
| | 80 | |
| | 81 | * Revision method 'serialize'. |
| | 82 | |
| | 83 | * Diff method 'serialize'. |
| | 84 | |
| | 85 | * API access to revisions: /api/rest/revision?since=ab49f348-fd23-ae3c |
| | 86 | |
| | 87 | * API access to diffs: /api/ |
| | 88 | |
| | 89 | * Repository method 'import_revisions'. It takes serialised revisions and diffs and creates |
| | 90 | |
| | 91 | * Object method 'merge_diffs'. It takes an original object and two diffs that apply to it and applies them both in a new revision. |