Package com.droidkit.actors.mailbox

Source Code of com.droidkit.actors.mailbox.MailboxesDispatcher

package com.droidkit.actors.mailbox;

import com.droidkit.actors.ActorRef;
import com.droidkit.actors.ActorScope;
import com.droidkit.actors.ActorSystem;
import com.droidkit.actors.Props;
import com.droidkit.actors.dispatch.AbstractDispatchQueue;
import com.droidkit.actors.messages.DeadLetter;
import com.droidkit.actors.messages.StartActor;

import java.util.HashMap;
import java.util.UUID;

/**
* Main actor model dispatcher for multiple mailboxes
*
* @author Stepan Ex3NDR Korshakov (me@ex3ndr.com)
*/
public class MailboxesDispatcher extends AbsMailboxesDispatcher {

    private final HashMap<Mailbox, ActorScope> mailboxes = new HashMap<Mailbox, ActorScope>();
    private final HashMap<String, ActorScope> scopes = new HashMap<String, ActorScope>();
    private final HashMap<String, Props> actorProps = new HashMap<String, Props>();

    private final ActorSystem actorSystem;

    /**
     * Creating dispatcher for actor system
     *
     * @param actorSystem  system
     * @param threadsCount number of threads
     */
    public MailboxesDispatcher(ActorSystem actorSystem, int threadsCount) {
        this(actorSystem, threadsCount, new MailboxesQueue());
    }

    /**
     * Creating dispatcher for actor system
     *
     * @param actorSystem  system
     * @param threadsCount number of threads
     * @param priority     threads priority
     */
    public MailboxesDispatcher(ActorSystem actorSystem, int threadsCount, int priority) {
        this(actorSystem, priority, threadsCount, new MailboxesQueue());
    }

    /**
     * Creating dispatcher for actor system
     *
     * @param actorSystem  system
     * @param threadsCount number of threads
     * @param priority     threads priority
     * @param queue        Mailboxes queue
     */
    public MailboxesDispatcher(ActorSystem actorSystem, int threadsCount, int priority, MailboxesQueue queue) {
        super(threadsCount, priority, queue);
        this.actorSystem = actorSystem;
    }

    /**
     * Creating dispatcher for actor system
     *
     * @param actorSystem  system
     * @param threadsCount number of threads
     * @param queue        Mailboxes queue
     */
    public MailboxesDispatcher(ActorSystem actorSystem, int threadsCount, MailboxesQueue queue) {
        super(threadsCount, queue);
        this.actorSystem = actorSystem;
    }

    @Override
    public ActorScope createScope(String path, Props props) {
        // TODO: add path check

        Mailbox mailbox = new Mailbox(getQueue());
        UUID uuid = UUID.randomUUID();
        ActorRef ref = new ActorRef(actorSystem, this, uuid, path);
        ActorScope scope = new ActorScope(actorSystem, mailbox, ref, this, UUID.randomUUID(), path, props);

        synchronized (mailboxes) {
            mailboxes.put(mailbox, scope);
            scopes.put(scope.getPath(), scope);
            actorProps.put(path, props);
        }

        // Sending init message
        scope.getActorRef().send(StartActor.INSTANCE);
        return scope;
    }

    @Override
    public void disconnectScope(ActorScope scope) {
        synchronized (mailboxes) {
            mailboxes.remove(scope.getMailbox());
            scopes.remove(scope.getPath());
        }
        for (Envelope envelope : scope.getMailbox().allEnvelopes()) {
            if (envelope.getSender() != null) {
                envelope.getSender().send(new DeadLetter(envelope.getMessage()));
            }
        }
    }

    @Override
    public void sendMessage(String path, Object message, long time, ActorRef sender) {
        synchronized (mailboxes) {
            if (!scopes.containsKey(path)) {
                if (sender != null) {
                    sender.send(new DeadLetter(message));
                }
            } else {
                Mailbox mailbox = scopes.get(path).getMailbox();
                mailbox.schedule(new Envelope(message, mailbox, sender), time);
            }
        }
    }

    @Override
    public void sendMessageOnce(String path, Object message, long time, ActorRef sender) {
        synchronized (mailboxes) {
            if (!scopes.containsKey(path)) {
                if (sender != null) {
                    sender.send(new DeadLetter(message));
                }
            } else {
                Mailbox mailbox = scopes.get(path).getMailbox();
                mailbox.scheduleOnce(new Envelope(message, mailbox, sender), time);
            }
        }
    }

    /**
     * Getting mailbox for actor
     *
     * @param mailbox mailbox
     * @return ActorScope or null if there are no actors for mailbox
     */
    protected ActorScope getMailboxActor(Mailbox mailbox) {
        synchronized (mailboxes) {
            return mailboxes.get(mailbox);
        }
    }

    @Override
    protected void dispatchMessage(Envelope envelope) {
        try {
            ActorScope actor = getMailboxActor(envelope.getMailbox());
            processEnvelope(envelope, actor);
        } finally {
            // TODO: better design
            getQueue().unlockMailbox(envelope.getMailbox());
        }
    }
}
TOP

Related Classes of com.droidkit.actors.mailbox.MailboxesDispatcher

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.