On Wed, Jul 27, 2005 at 11:40:07AM -0400, Geo Carncross wrote: > Because that's not what IMAP flags are. They're individual > annotations to a message, not a single annotation - as all the flags > and keywords combined.
How does dbmail store flags? If it stored each flag as a separate entry in a relational table, you're covered. If not, you're not. > Clearly if a client said "STORE FLAGS (\Answered)" "STORE FLAGS > (+FOOBaz)" they wouldn't care, but if they said: > > STORE +FLAGS (\Answered) > STORE +FLAGS (+FOOBaz) > > they really mean for both of those flags to be stored. Not necessarily. You're assuming that the protocol's semantics are reflecting what the user means to do, which is not necessarily the case in multimaster (especially since the RFC says it assumes a single master!) In particular, say you have the following: Servers A and B have an email, UID 9, which has no flags set. Servers A and B lose sync. User connects to A, reads mail, decides to set flag +FOOBaz. MUA chooses to implement this as STORE +FLAGS (+FOOBaz) User disconnects User connects to B, reads mail, notices that flag +FOOBaz WAS NOT SET, decides that's OK and that he just wants \Answered set. MUA chooses to implement this as STORE +FLAGS (\Answered). Note that if the user had wanted +FOOBaz as well, he'd have clicked that, too, and the MUA would have run STORE +FLAGS (\Answered +FOOBaz) User calls helpdesk to complain that flag mysteriously disappeared. They tell him to try setting it again. He says he doesn't want it any longer, he was just calling to find out what happened to it. They say they're having some weird mail server problems, but he should still be able to read his email. Servers A and B regain sync, replicate, and merge flags. User connects to B again. Now +FOOBaz and \Answered are set. User calls helpdesk again because the flag has mysteriously reappeared. Helpdesk throws up hands in frustration. But again -- if you choose to implement flags relationally, using a flag per row, this kind of problem should be resolved the way you expect. When A interprets STORE +FLAGS (+FOOBaz), it runs something like INSERT INTO flag_table values (9, "+FOOBaz"). When B interprets STORE +FLAGS (\Answered), it runs something like INSERT INTO flag_table values (9, "\Answered). When replication occurs, there are two entries in flag_table for UID 9, one for "+FOOBaz", one for "\Answered". This is what you expect, right? The semantics of flags in a multimaster world are subtle. What does the user expect when the client does a set rather than an add, ie. "STORE FLAGS (+FOOBaz)" in one session to one server, and "STORE FLAGS (\Answered)" in another? Ie. if there are no flags set to begin with, does "set" reflect the user's preference, or does it reflect the client's belief that there are no other flags set, so setting and adding are equivalent ops? IMHO, the semantics here are non-trivial. > Consider an IMAP agent that periodically marks messages with the > "Junk" keyword. Suddenly those flags disappear- but the message is > no longer \Recent so that clients remove the junk-status. > If someone leaves their Thunderbird all day, but periodically opens > with Eudora, they've lost their junk-scanning abilities. I'm not sure I follow this as a problem. If the user has two different clients running, even to the same server without any kind of server clustering, each session is guaranteed to see different messages as \Recent per the RFC, so the two sessions should interfere with each other. \Recent is a session flag, so it shouldn't be stored in the DB to be persistent across sessions, and shouldn't cause (additional) problems in a multimaster world. The client MUST NOT be able to set or unset \Recent explicitly with any IMAP ops per the RFC. That said, if you are storing \Recent persistently, that's OK so long as you're using a different row for each flag. Ie.: Multimaster servers A and B are out-of-sync, but they each have an email, UID 9, with \Recent set. client 1 on server A sets Junk and implicitly unsets \Recent by logging out A runs: insert into flag_table values (9, "Junk"); A runs: delete from flag_table where uid=9 and flag="\Recent" Client 2 on server B implicitly unsets \Recent by logging out B runs: delete from flag_table where uid=9 and flag="\Recent" A and B sync. replication catches up. End state has UID 9 with flag Junk and no flag "\Recent", as expected. Again, the question is, how does dbmail store flags? - Morty