WaitSet: scalable mechanism for listening for changes to one or more accounts -------------------------------------------------------------------------------- Non-admin versions in the 'zimbraMail' Namespace: ------------------------------------------------- Admin versions in the 'zimbraAdmin' Namespace: ------------------------------------------------- note that the admin versions of the APIs are identical in any way, except that they can be used to wait on non-owner accounts and can be used to wait on "all accounts". ************************************* INTEREST_TYPES: comma-separated list. Currently: f: folders m: messages c: contacts a: appointments t: tasks d: documents all: all types (equiv to "f,m,c,a,t,d") ************************************* CreateWaitSet/AdminCreateWaitSet: must be called once to initialize the WaitSet and to set its "default interest types" - Non-Admin requests may only specify their own account ID. - Non-Admin accounts are restricted to a max of 5 (default, overridable via LocalConfig) WaitSets. Creating more than the max will cause the least-recently-used WaitSet to be destroyed - If "allAccounts" is set, then all mailboxes on the system will be listened to, including any mailboxes which are created on the system while the WaitSet is in existence. Additionally: -- , and tags are IGNORED -- The requesting authtoken must be an admin token - AllAccounts WaitSets are *semi-persistent*, that is, even if the server restarts, it is OK to call passing in your previous sequence number. The server will attempt to resynchronize the waitset using the sequence number you provide (the server's ability to do this is limited by the RedoLogs that are available) ================ <[Admin]CreateWaitSetRequest defTypes="DEFAULT INTEREST_TYPES" [allAccounts=1]> [ []+ ] <[Admin]CreateWaitSetResponse waitSet="setId" defTypes="types" seq="0"> [ ]* ERROR_CODEs: // RUNTIME errors: MAILBOX_DELETED: the mailbox has been deleted, it is no longer in the waitset // ADD errors: ALREADY_IN_SET_DURING_ADD: the account was not added, it was already there ERROR_LOADING_MAILBOX: exception while trying to fetch the mailbox, not added MAINTENANCE_MODE: mailbox currently in Maintenance Mode. Try to add it again later. NO_SUCH_ACCOUNT: unknown account, not added WRONG_HOST_FOR_ACCOUNT: that account's mailbox is on another host. Add it there. // REMOVE/UPDATE errors NOT_IN_SET_DURING_REMOVE NOT_IN_SET_DURING_UPDATE ***IMPORTANT: Note that the seq number is **NOT** guaranteed to be an integer. Clients MUST treat this value as an opaque string.*** ************************************ WaitSetRequest/AdminWaitSetRequest: optionally modifies the wait set and checks for any notifications. If block=1 and there are no notifications, then this API will BLOCK until there is data. Client should always set 'seq' to be the highest known value it has received from the server. The server will use this information to retransmit lost data. If the client sends a last known sync token then the notification is calculated by comparing the accounts current token with the client's last known. If the client does not send a last known sync token, then notification is based on change since last Wait (or change since if this is the first time Wait has been called with the account) The client may specify a custom timeout-length for their request if they know something about the particular underlying network. The server may or may not honor this request (depending on server configured max/min values). The server will allow a wider range of requested timeouts from admin auth tokens. See LocalConfig values: zimbra_waitset_default_request_timeout, zimbra_waitset_min_request_timeout, zimbra_waitset_max_request_timeout, zimbra_admin_waitset_default_request_timeout, zimbra_admin_waitset_min_request_timeout, and zimbra_admin_waitset_max_request_timeout ================ <[Admin]WaitSetRequest waitSet="setId" defTypes="DEFAULT INTEREST TYPES" seq="highestSeqKnown" [block="1"] [timeout="timeout"]> [ []+ ] [ []+ ] [ []+ ] <[Admin]WaitSetResponse waitSet="setId" [seq="seqNo" OR canceled="1"]> [ ]* [ ]* If the specified wait set does not exist, the server will throw an admin.NO_SUCH_WAITSET exception. NOTE: an empty response to a blocking request *is* possible: it would happen if the server timed-out the waiting. The server does this occasionally just so that requests don't get "stuck". The client should re-submit the original request if this happens. If a second WaitMultiple request arrives at the server while one is already waiting, the first request will be immediately completed and will return with the "canceled" flag set. ERROR_CODEs: // RUNTIME errors: MAILBOX_DELETED: the mailbox has been deleted, it is no longer in the waitset // ADD errors: ALREADY_IN_SET_DURING_ADD: the account was not added, it was already there ERROR_LOADING_MAILBOX: exception while trying to fetch the mailbox, not added MAINTENANCE_MODE: mailbox currently in Maintenance Mode. Try to add it again later. NO_SUCH_ACCOUNT: unknown account, not added WRONG_HOST_FOR_ACCOUNT: that account's mailbox is on another host. Add it there. // REMOVE/UPDATE errors NOT_IN_SET_DURING_REMOVE NOT_IN_SET_DURING_UPDATE ************************************* DestroyWaitSet/AdminDestroyWaitSet: Use this to close out the wait set. Note that the server will automatically time out a wait set if there is no reference to it for (default of) 20 minutes. ************************************* <[Admin]DestroyWaitSetRequest waitSet="setId"/> <[Admin]DestroyWaitSetResponse waitSet="setId"/> ********************************************************************** There are three basic use cases for WaitSets: ********************************************************************** 1) wait on a single account: 2) Wait on many accounts (admin-only -- Remember to use the zimbraAdmin namespace): 3) Wait on ALL accounts (admin-only): ... // SERVER RESTARTS! ... // server will re-sync using RedoLogs ********************************************************************** A Detailed Example: ********************************************************************** ************************************* QueryWaitSet This API dumps the internal state of all active waitsets. It is intended for debugging use only and should not be used for production uses. This API is not guaranteed to be stable between releases in any way and might be removed without warning. ************************************* SomeAccountsWaitSet: ---------------------- []? [ [ ]? ]* AllAccountsWaitSet: ------------------- [ []* // only during WS creation before first WaitSetRequest ]? []?