Skip to content

Event is lost after unregister/ #95

@KadarRobert

Description

@KadarRobert

Hello,
I've a found a corner case when you post an event (non-main-thread) to a MainThread the event is lost and no NoSubscriberEvent is sent.

Latest code from git.
Steps:
1.) Post an Event from a non-main-thread.
2.) Unregister after the post method was called.

Expected:
2.) A NoSubscriberEvent should be sent.

Actual:
2.) The event is lost.

I've created a a Unit test to ilustrate this issue.

public class TestPostingIssue extends AbstractEventBusTest {

    // this test will fail.
    public void testNoEventDelivered() {
        // I've created a dummy class to ilustrate the corner case issue.
        TestClass testClass = new TestClass();

        /**
         * Basically register a class, post an event and unregister the class.
         * The event will not be sent and also no NoSubscriberEvent will be
         * deliver. I couldn't find any warnings in the logs.
         */
        eventBus.register(testClass);
        // a new String Event is posted from the Test Thread to the MainThread.
        eventBus.post(new String("Test"));
        eventBus.unregister(testClass);

        try {
            // sleep 1sec just to be sure.
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Test if we received a NoSubscriberEvent then there should not be
        // any String Event. Else we should have received the String Event.
        if (testClass.getNoSubscriberEvent() != null) {
            assertNull(testClass.getStringValue());
        } else {
            assertNotNull(testClass.getStringValue());
        }
    }

    // this test will not fail.
    public void testEventDeliverd() {
        final TestClass testClass = new TestClass();
        eventBus.register(testClass);
        // a new String Event is posted from the Main Thread to the MainThread.

        Handler handler = new Handler(Looper.getMainLooper());
        handler.post(new Runnable() {
            @Override
            public void run() {
                eventBus.post(new String("Test"));
                eventBus.unregister(testClass);
            }
        });

        try {
            // sleep 1sec just to be sure.
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        // Test if we received a NoSubscriptionEvent then there should not be
        // any String Event. Else we should have received the String Event.
        if (testClass.getNoSubscriberEvent() != null) {
            assertNull(testClass.getStringValue());
        } else {
            assertNotNull(testClass.getStringValue());
        }
    }

    private static class TestClass {

        private String stringValue;
        private NoSubscriberEvent noSubscriberEvent;

        public void onEventMainThread(String event) {
            stringValue = event;
        }

        public void onEventMainThread(NoSubscriberEvent event) {
            noSubscriberEvent = event;
        }

        public NoSubscriberEvent getNoSubscriberEvent() {
            return noSubscriberEvent;
        }

        public String getStringValue() {
            return stringValue;
        }
    }

}

Hope this is helpful.

Thanks,

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions