Skip to content

Pattern 2: Mailbox

pewsou edited this page Jun 18, 2022 · 6 revisions

Intro

Mailbox's idea is simple: a user creates standalone FIFO container, where other users may put asynchronously messages, and the owner may read them later.

Also Groups introduced: this is FIFO container too, but some other users may be allowed to read messages.

Container may be configured to be temporary or permanent.

Additionally there is authorization manager, that helps to ensure that operations performed by eligible users only. Almost every operation requires some Secret as an argument; the Secret is an object encapsulation the proof of invokers eligibility.

Current set of capabilities and properties:

  1. One can create standalone Mailbox/Group, destroy it, read and remove messages.
  2. One can configure the facility for range of properties, for example: set low/high limits of container capacity, update secrets and more.
  3. Containers may be configured for self-destruction after time period; same about messages.
  4. Broadcast and multicast supported: messages may be sent to all containers at once, or to private containers of members of some group.
  5. Container may establish low/high thresholds for message quantity: low threshold implies that while number of messages is under this value they could not be read; high threshold implies that FIFO queue size cannot excess this number, so when new message cast, some will be dropped. It is possible to select the dropping policy: whether to drop new message, or the oldest message, or drop the message using some more complex algorithm.

Blocking interface

There is a way to deliver messages in synchronous way, i.e. once some thread calls a method for message posting it will return only when the message was read. Alternatively, reverse way is available too: reading thread may be suspended on empty mailbox; it will be released when message enters or container is deleted.

The corresponding API looks like that:

-(NSArray*) waitAndReadMsg:(NSRange)skipAndTake fromMailbox:(id)mid unblockIf:(ASFKMbLockConditionRoutine)condition withSecret:(ASFKPrivateSecret*)secret

-(id) call:(id)msg forMailbox:(id)uid withProperties:(ASFKMBMsgProperties*)props unblockIf:(ASFKCondition*)condition secret:(ASFKSecret*)secret

Usage:

First we create a standalone mailbox (same applicable to a group):

ASFKMailbox* mail=[ASFKMailbox sharedManager];

id status = [mail createMailbox:@"user1" withProperties:nil secret:nil];

Here we created a mailbox without properties and no secret.

Next we will put a message:

id msgId = [mail cast:@"Msg1" forMailbox:@"user1" withProperties:nil secret:nil];

Again no message property is specified and no secret.

Notice: _when message properties provided, some of them may be overriden by container's properties; for example, if container is set to self-destroy after 3 seconds, and message is set to 5 seconds, then corresponding message's property (if exists) will be set to 3 seconds. _

Next step - reading

NSArray* a=[mail readEarliestMsg:NSMakeRange(1,msgnum) fromMailbox:@"user1" withSecret:nil];

'a' is array of no more than 'msgnum' available messages starting from the second earliest, because 1 designates offset.

Deleting:

NSRange r; r.length=3;r.location=1;

NSUInteger a=[mail popLatestMsg:r fromMailbox:@"user1" withSecret:nil];

Here we delete from container maximum 3 latest messages, except for the latest. 'a' is number of actually deleted messages.

Moderation

There is some functionality managing behavior of writers/readers. For example, some users may be banned from posting or reading messages to/from specific container. Here is the code snippet illustrating that concept:

[mail mute:YES user:@"someuser" inMailbox:@"Some mailbox" secret:nil]; //forbid posting by user "someuser"

[mail blind:YES user:@"someuser" inMailbox:@"Some mailbox" secret:nil]; //forbid reading by user "someuser"

Also message can be retracted, using this API:

[mail retractMsg:@"msgId" fromMailbox:@"Some mailbox" secret:nil];

Here 'msgId' is some identifier returned by 'cast' operation.

Message can be hidden. It means, it is possible to cast/call message that will not be available for reading until time is right. this is achieved by using regular cast/call API with property of type ASFKMBMsgProperties. When this property has field 'msgReadabilityTimer' initialized with some time delay value, the message will not be available for reading until the time comes up.

Deferred delivery and deletion

Messages are not necessarily delivered immediately; deletions is not immediate neither. For example, broadcasting to large number of mailboxes may take a lot of time, so it is designed to be done on portions. To ensure all messages delivered and all deletion candidates deleted, it is needed to invoke periodically method

[mail runDaemon:num_of_steps timepoint:[NSDate date] callbacks:nil];

Secrets

Secrets are tokens, requested by almost all operations. If container is not configured to use tokens, the corresponding parameter of method call can be set to nil; otherwise, correct secret must be provided. If the secret does not matche the secret stored in container, then operation fails. There are 3 main types of secrets: Master/Group/Private and each secret may have different roles: Writer, Reader, Unicaster and so on. Private secrets are to be used in Mailbox by its owner; Group secret may be used on group only by any group member; Master secret is used for system-wide operations, like configuration. Hierarchically, Master secret overrides Private and Group in operations that are compliant with Master.

Clone this wiki locally