Package co.paralleluniverse.actors

Source Code of co.paralleluniverse.actors.ActorTest$TypedReceiveA

/*
* Quasar: lightweight threads and actors for the JVM.
* Copyright (c) 2013-2014, Parallel Universe Software Co. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*   or (per the licensee's choosing)
* under the terms of the GNU Lesser General Public License version 3.0
* as published by the Free Software Foundation.
*/
package co.paralleluniverse.actors;

import co.paralleluniverse.common.util.Debug;
import co.paralleluniverse.common.util.Exceptions;
import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.fibers.FiberForkJoinScheduler;
import co.paralleluniverse.fibers.FiberScheduler;
import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.strands.Strand;
import co.paralleluniverse.strands.channels.Channel;
import co.paralleluniverse.strands.channels.Channels;
import co.paralleluniverse.strands.channels.SendPort;
import com.google.common.base.Function;
import com.google.common.base.Predicate;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicBoolean;
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.*;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;

/**
*
* @author pron
*/
public class ActorTest {
    @BeforeClass
    public static void beforeClass() {
        Debug.dumpAfter(10000);
    }
    static final MailboxConfig mailboxConfig = new MailboxConfig(10, Channels.OverflowPolicy.THROW);
    private FiberScheduler scheduler;

    public ActorTest() {
        scheduler = new FiberForkJoinScheduler("test", 4, null, false);
    }

    private <Message, V> Actor<Message, V> spawnActor(Actor<Message, V> actor) {
        Fiber fiber = new Fiber("actor", scheduler, actor);
        fiber.setUncaughtExceptionHandler(new Strand.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Strand s, Throwable e) {
                e.printStackTrace();
                throw Exceptions.rethrow(e);
            }
        });
        fiber.start();
        return actor;
    }

    @Test
    public void whenActorThrowsExceptionThenGetThrowsIt() throws Exception {
        Actor<Message, Integer> actor = spawnActor(new BasicActor<Message, Integer>(mailboxConfig) {
            @Override
            protected Integer doRun() throws SuspendExecution, InterruptedException {
                throw new RuntimeException("foo");
            }
        });

        try {
            actor.get();
            fail();
        } catch (ExecutionException e) {
            assertThat(e.getCause(), instanceOf(RuntimeException.class));
            assertThat(e.getCause().getMessage(), is("foo"));
        }
    }

    @Test
    public void whenActorThrowsExceptionThenGetThrowsItThreadActor() throws Exception {
        Actor<Message, Integer> actor = new BasicActor<Message, Integer>(mailboxConfig) {
            @Override
            protected Integer doRun() throws SuspendExecution, InterruptedException {
                throw new RuntimeException("foo");
            }
        };

        actor.spawnThread();

        try {
            actor.get();
            fail();
        } catch (ExecutionException e) {
            assertThat(e.getCause(), instanceOf(RuntimeException.class));
            assertThat(e.getCause().getMessage(), is("foo"));
        }
    }

    @Test
    public void whenActorReturnsValueThenGetReturnsIt() throws Exception {
        Actor<Message, Integer> actor = spawnActor(new BasicActor<Message, Integer>(mailboxConfig) {
            @Override
            protected Integer doRun() throws SuspendExecution, InterruptedException {
                return 42;
            }
        });

        assertThat(actor.get(), is(42));
    }

    @Test
    public void whenActorReturnsValueThenGetReturnsItThreadActor() throws Exception {
        Actor<Message, Integer> actor = new BasicActor<Message, Integer>(mailboxConfig) {
            @Override
            protected Integer doRun() throws SuspendExecution, InterruptedException {
                return 42;
            }
        };

        actor.spawnThread();

        assertThat(actor.get(), is(42));
    }

    @Test
    public void testReceive() throws Exception {
        ActorRef<Message> actor = new BasicActor<Message, Integer>(mailboxConfig) {
            @Override
            protected Integer doRun() throws SuspendExecution, InterruptedException {
                Message m = receive();
                return m.num;
            }
        }.spawn();

        actor.send(new Message(15));

        assertThat(LocalActor.<Integer>get(actor), is(15));
    }

    @Test
    public void testReceiveThreadActor() throws Exception {
        ActorRef<Message> actor = new BasicActor<Message, Integer>(mailboxConfig) {
            @Override
            protected Integer doRun() throws SuspendExecution, InterruptedException {
                Message m = receive();
                return m.num;
            }
        }.spawnThread();

        actor.send(new Message(15));

        assertThat(LocalActor.<Integer>get(actor), is(15));
    }

    @Test
    public void testReceiveAfterSleep() throws Exception {
        ActorRef<Message> actor = new BasicActor<Message, Integer>(mailboxConfig) {
            @Override
            protected Integer doRun() throws SuspendExecution, InterruptedException {
                Message m1 = receive();
                Message m2 = receive();
                return m1.num + m2.num;
            }
        }.spawn();

        actor.send(new Message(25));
        Thread.sleep(200);
        actor.send(new Message(17));

        assertThat(LocalActor.<Integer>get(actor), is(42));
    }

    @Test
    public void testReceiveAfterSleepThreadActor() throws Exception {
        ActorRef<Message> actor = new BasicActor<Message, Integer>(mailboxConfig) {
            @Override
            protected Integer doRun() throws SuspendExecution, InterruptedException {
                Message m1 = receive();
                Message m2 = receive();
                return m1.num + m2.num;
            }
        }.spawnThread();

        actor.send(new Message(25));
        Thread.sleep(200);
        actor.send(new Message(17));

        assertThat(LocalActor.<Integer>get(actor), is(42));
    }

    private class TypedReceiveA {
    };

    private class TypedReceiveB {
    };

    @Test
    public void testTypedReceive() throws Exception {
        Actor<Object, List<Object>> actor = spawnActor(new BasicActor<Object, List<Object>>(mailboxConfig) {
            @Override
            protected List<Object> doRun() throws InterruptedException, SuspendExecution {
                List<Object> list = new ArrayList<>();
                list.add(receive(TypedReceiveA.class));
                list.add(receive(TypedReceiveB.class));
                return list;
            }
        });
        final TypedReceiveB typedReceiveB = new TypedReceiveB();
        final TypedReceiveA typedReceiveA = new TypedReceiveA();
        actor.ref().send(typedReceiveB);
        Thread.sleep(2);
        actor.ref().send(typedReceiveA);
        assertThat(actor.get(500, TimeUnit.MILLISECONDS), equalTo(Arrays.asList(typedReceiveA, typedReceiveB)));
    }

    @Test
    public void testSelectiveReceive() throws Exception {
        Actor<ComplexMessage, List<Integer>> actor = spawnActor(new BasicActor<ComplexMessage, List<Integer>>(mailboxConfig) {
            @Override
            protected List<Integer> doRun() throws SuspendExecution, InterruptedException {
                final List<Integer> list = new ArrayList<>();
                for (int i = 0; i < 2; i++) {
                    receive(new MessageProcessor<ComplexMessage, ComplexMessage>() {
                        public ComplexMessage process(ComplexMessage m) throws SuspendExecution, InterruptedException {
                            switch (m.type) {
                                case FOO:
                                    list.add(m.num);
                                    receive(new MessageProcessor<ComplexMessage, ComplexMessage>() {
                                        public ComplexMessage process(ComplexMessage m) throws SuspendExecution, InterruptedException {
                                            switch (m.type) {
                                                case BAZ:
                                                    list.add(m.num);
                                                    return m;
                                                default:
                                                    return null;
                                            }
                                        }
                                    });
                                    return m;
                                case BAR:
                                    list.add(m.num);
                                    return m;
                                case BAZ:
                                    fail();
                                default:
                                    return null;
                            }
                        }
                    });
                }
                return list;
            }
        });

        actor.ref().send(new ComplexMessage(ComplexMessage.Type.FOO, 1));
        actor.ref().send(new ComplexMessage(ComplexMessage.Type.BAR, 2));
        actor.ref().send(new ComplexMessage(ComplexMessage.Type.BAZ, 3));

        assertThat(actor.get(), equalTo(Arrays.asList(1, 3, 2)));
    }

    @Test
    public void whenSimpleReceiveAndTimeoutThenReturnNull() throws Exception {
        Actor<Message, Void> actor = spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                Message m;
                m = receive(100, TimeUnit.MILLISECONDS);
                assertThat(m.num, is(1));
                m = receive(100, TimeUnit.MILLISECONDS);
                assertThat(m.num, is(2));
                m = receive(100, TimeUnit.MILLISECONDS);
                assertThat(m, is(nullValue()));

                return null;
            }
        });

        actor.ref().send(new Message(1));
        Thread.sleep(20);
        actor.ref().send(new Message(2));
        Thread.sleep(200);
        actor.ref().send(new Message(3));
        actor.join();
    }

    @Test
    public void testTimeoutException() throws Exception {
        Actor<Message, Void> actor = spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                try {
                    receive(100, TimeUnit.MILLISECONDS, new MessageProcessor<Message, Message>() {
                        public Message process(Message m) throws SuspendExecution, InterruptedException {
                            fail();
                            return m;
                        }
                    });
                    fail();
                } catch (TimeoutException e) {
                }
                return null;
            }
        });

        Thread.sleep(150);
        actor.ref().send(new Message(1));
        actor.join();
    }

    @Test
    public void testSendSync() throws Exception {
        final Actor<Message, Void> actor1 = spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                Message m;
                m = receive();
                assertThat(m.num, is(1));
                m = receive();
                assertThat(m.num, is(2));
                m = receive();
                assertThat(m.num, is(3));
                return null;
            }
        });

        final Actor<Message, Void> actor2 = spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                Fiber.sleep(20);
                actor1.ref().send(new Message(1));
                Fiber.sleep(10);
                actor1.sendSync(new Message(2));
                actor1.ref().send(new Message(3));
                return null;
            }
        });

        actor1.join();
        actor2.join();
    }

    @Test
    public void testLink() throws Exception {
        Actor<Message, Void> actor1 = spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                Fiber.sleep(100);
                return null;
            }
        });

        Actor<Message, Void> actor2 = spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                try {
                    for (;;) {
                        receive();
                    }
                } catch (LifecycleException e) {
                }
                return null;
            }
        });

        actor1.link(actor2.ref());

        actor1.join();
        actor2.join();
    }

    @Test
    public void testWatch() throws Exception {
        Actor<Message, Void> actor1 = spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                Fiber.sleep(100);
                return null;
            }
        });

        final AtomicBoolean handlerCalled = new AtomicBoolean(false);

        Actor<Message, Void> actor2 = spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                Message m = receive(200, TimeUnit.MILLISECONDS);
                assertThat(m, is(nullValue()));
                return null;
            }

            @Override
            protected Message handleLifecycleMessage(LifecycleMessage m) {
                super.handleLifecycleMessage(m);
                handlerCalled.set(true);
                return null;
            }
        });

        actor2.watch(actor1.ref());

        actor1.join();
        actor2.join();

        assertThat(handlerCalled.get(), is(true));
    }

    @Test
    public void testWatchGC() throws Exception {
        Assume.assumeFalse(Debug.isDebug());
       
        final Actor<Message, Void> actor = spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                Fiber.sleep(120000);
                return null;
            }
        });
        System.out.println("actor1 is " + actor);
        WeakReference wrActor2 = new WeakReference(spawnActor(new BasicActor<Message, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                Fiber.sleep(10);
                final Object watch = watch(actor.ref());
//                unwatch(actor, watch);
                return null;
            }
        }));
        System.out.println("actor2 is " + wrActor2.get());
        for (int i = 0; i < 10; i++) {
            Thread.sleep(10);
            System.gc();
        }
        Thread.sleep(2000);

        assertEquals(null, wrActor2.get());
    }

    @Test
    public void transformingSendChannelIsEqualToActor() throws Exception {
        final ActorRef<Integer> actor = new BasicActor<Integer, Void>(mailboxConfig) {
            @Override
            protected Void doRun() throws SuspendExecution, InterruptedException {
                return null;
            }
        }.spawn();

        SendPort<Integer> ch1 = Channels.filterSend(actor, new Predicate<Integer>() {
            @Override
            public boolean apply(Integer input) {
                return input % 2 == 0;
            }
        });
        SendPort<Integer> ch2 = Channels.mapSend(actor, new Function<Integer, Integer>() {
            @Override
            public Integer apply(Integer input) {
                return input + 10;
            }
        });

        assertTrue(ch1.equals(actor));
        assertTrue(actor.equals(ch1));
        assertTrue(ch2.equals(actor));
        assertTrue(actor.equals(ch2));
    }

    static class Message {
        final int num;

        public Message(int num) {
            this.num = num;
        }
    }

    static class ComplexMessage {
        enum Type {
            FOO, BAR, BAZ, WAT
        }
        final Type type;
        final int num;

        public ComplexMessage(Type type, int num) {
            this.type = type;
            this.num = num;
        }
    }
}
TOP

Related Classes of co.paralleluniverse.actors.ActorTest$TypedReceiveA

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.