Skip to content

Commit abe2823

Browse files
authored
Merge pull request ably#599 from ably/feature/598-discard-persisted-events
Discard persisted events with non-nullary constructors
2 parents 756f52b + d7a9669 commit abe2823

2 files changed

Lines changed: 43 additions & 2 deletions

File tree

android/src/androidTest/java/io/ably/lib/test/android/AndroidPushTest.java

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,6 +1385,33 @@ public Void apply(TestActivation.Options options) throws AblyException {
13851385
assertInstanceOf(AfterRegistrationSyncFailed.class, activation.machine.current);
13861386
}
13871387

1388+
// https://github.com/ably/ably-java/issues/598
1389+
public void test_restore_non_nullary_event() {
1390+
TestActivation activation = new TestActivation();
1391+
assertInstanceOf(NotActivated.class, activation.machine.current);
1392+
1393+
SyncRegistrationFailed event = new SyncRegistrationFailed(new ErrorInfo());
1394+
1395+
activation.machine.handleEvent(event);
1396+
1397+
// NotActivated can't handle SyncRegistrationFailed, so it should be pending.
1398+
assertTrue(activation.machine.pendingEvents.contains(event));
1399+
1400+
// Now recover the persisted state and events.
1401+
1402+
activation = new TestActivation(new Helpers.AblyFunction<TestActivation.Options, Void>() {
1403+
@Override
1404+
public Void apply(TestActivation.Options options) throws AblyException {
1405+
options.clearPersisted = false;
1406+
return null;
1407+
}
1408+
});
1409+
1410+
// Since the event doesn't have a nullary constructor, it should be dropped.
1411+
assertInstanceOf(NotActivated.class, activation.machine.current);
1412+
assertSize(0, activation.machine.pendingEvents);
1413+
}
1414+
13881415
// This is all copied and pasted from ParameterizedTest, since I can't inherit from it.
13891416
// I need to inherit from AndroidPushTest, and Java doesn't have multiple inheritance
13901417
// or mixins or something like that.

android/src/main/java/io/ably/lib/push/ActivationStateMachine.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,6 +573,9 @@ public synchronized boolean handleEvent(ActivationStateMachine.Event event) {
573573
// An event's side effects may end up synchronously calling handleEvent while it's
574574
// itself being handled. In that case, enqueue it so it's handled next (and still
575575
// synchronously).
576+
//
577+
// We don't need to persist here, as the handleEvent call up the stack will eventually
578+
// persist when done with the synchronous transitions.
576579
enqueueEvent(event);
577580
return true;
578581
}
@@ -584,7 +587,7 @@ public synchronized boolean handleEvent(ActivationStateMachine.Event event) {
584587
ActivationStateMachine.State maybeNext = current.transition(event);
585588
if (maybeNext == null) {
586589
enqueueEvent(event);
587-
return true;
590+
return persist();
588591
}
589592

590593
Log.d(TAG, String.format("transition: %s -(%s)-> %s", current.getClass().getSimpleName(), event.getClass().getSimpleName(), maybeNext.getClass().getSimpleName()));
@@ -675,7 +678,18 @@ private ArrayDeque<ActivationStateMachine.Event> getPersistedPendingEvents() {
675678
for (int i = 0; i < length; i++) {
676679
try {
677680
String className = activationContext.getPreferences().getString(String.format("%s[%d]", ActivationStateMachine.PersistKeys.PENDING_EVENTS_PREFIX, i), "");
678-
ActivationStateMachine.Event event = ((Class<ActivationStateMachine.Event>) Class.forName(className)).newInstance();
681+
Class<ActivationStateMachine.Event> eventClass = (Class<ActivationStateMachine.Event>) Class.forName(className);
682+
ActivationStateMachine.Event event;
683+
try {
684+
event = eventClass.newInstance();
685+
} catch(InstantiationException e) {
686+
// We aren't properly persisting events with a non-nullary constructor. Those events
687+
// are supposed to be handled by states that aren't persisted (until
688+
// https://github.com/ably/ably-java/issues/546 is fixed), so it should be safe to
689+
// just drop them.
690+
Log.d(TAG, String.format("discarding improperly persisted event: %s", className));
691+
continue;
692+
}
679693
deque.add(event);
680694
} catch(Exception e) {
681695
throw new RuntimeException(e);

0 commit comments

Comments
 (0)