Hi Alex, For ID generation, you are in a bit of a bind. If the client needs to generate GUIDs reliably offline, then it must generate them on its own (without information from a remote service). However, if it's generating them on it's own, there's no way to 100% guarantee uniqueness across different installations/browsers/clients.
One simple approach is to assign each client a globally unique ID during installation. (I assume that when the client first installs your Gears app, they must be online.) This can be a simple 64-bit number or a SHA1 hash of the current time in microseconds or something. Anything that your server can guarantee is unique for all time. The client then must generate a unique UUID that is unique for itself. So, many of the standard UUID techniques should work. Or, since Gears uses SQLite under the hood, you can check out it's ROWID or AUTO INCREMENT feature http://www.sqlite.org/autoinc.html When the client submits or synchronizes with your service, it sends both it's globally unique client id (assigned during installation) and the unique item id for each row it has made. Since the client submits each new item with both the client unique identifier and the row unique id, your service can be certain that the combination of "unique client id" + "unique row id within that client" will be globally unique. This might require some changes on your backend DB structure (since the primary key is the combination of 'client id' and 'client row id' rather than just a 'client row id'). But, this approach should be sufficient to guarantee that all clients are able to make universally unique IDs. HTH Dave Viner On Oct 7, 6:37 am, Alex Bertram <[email protected]> wrote: > Hi All, > > I'm getting into the nitty-gritty of replicating user data between the > server (managed by hibernate) and Gears-enabled web clients. > > The database in question is not that complicated, but even with a > small number of related tables there seem to be some tricky issues > that I'm anxious to get right. The two big issues I'm looking at are > 1/ change tracking and 2/ id generation, and I'm wondering whether > anyone out there has some experience with this and a few practical > tips. > > Change tracking on the server: Timestamps vs Sequence Id > --------------------------------------------------------------------------- > ---------------- > > Ideally, we want the client to send a single version number to the > server, and the server sends us back the changes that have been made > in subsequent updates. To do this, we need some kind of universal > generation or version index -- if we maintain version numbers at the > row level, clients would have to send us their version number for each > object in the local cache, right?? > > The easiest way to do this seems to be to add DateCreated and > DateModified columns to the table in question, and then use > myTable.getDateCreated().getTime() as our versionid of type long. > Every update sent to the client is labeled with a version number, so > we don't have to worry about the client having a different timezone or > users with their system clock sent back to 1970, but still, something > makes me nervous about this when thinking about concurrency issues and > the time between when, for example, (new Date()) is called and when an > updated record is actually committed. (anyone with horror stories?) > > The "right" way would be to use a single table to hold the current > version number, but this seems like it would create quite a > bottleneck. (Or am I overestimating the problem?) > > On the client, I don't think we need versioning, we just keep a list > of pending commands that need to be sent to the server. (Though what > happens if there's an inconsistency error, for example, someone else > has deleted a parent record or the user lost access to an object while > s/he was offline?? Ugh, to deal with later!) > > ID Generation > ----------------------------------------------------- > > The second big question I see is id generation. When the user creates > a new hierarchy of records, for example, a WorkSite row with 3 > dependent WeeklyReports, the client needs to be able to assign an Id > to the WorkSite independently of the server. > > In this case, the "simple" approach seems like GUID generation on the > client, but aside from increase in RPC size, my first reaction is to > be wary of how random the javascript Math.random() function is. Given > all the other problems with IE6, i can just imagine it cycling through > the same values every 60 minutes!! Am I being too paranoid? > > The two alternatives would be > > a/ periodically ask the server for a range of ids that are ok to use > (e.g. the hilo strategy or variants), risking to run out ids while > offline. > > b/ reserve a range of the ids for local use that are subsituted out > during synchronization (i.e. for a 32-bit integer id, the client is > allowed to use ids < 0, and the server generates replacements upon > receipt on the server-side, and then transmits the mapping back to the > client -- uggh in a word) > > Anyone have any experience using browser-generated GUIDs with moderate > through-put? > > Many thanks for any thoughts! > > Alex Bertram > Systems Analyst > UNICEF - DR Congo
