use of arez.spy.ActionCompletedEvent in project arez by arez.
the class ArezContext method safeAction.
private <T> T safeAction(@Nullable final String name, @Nullable final TransactionMode mode, @Nonnull final SafeFunction<T> action, @Nullable final Observer tracker, @Nonnull final Object... parameters) {
final boolean tracked = null != tracker;
Throwable t = null;
boolean completed = false;
long startedAt = 0L;
T result;
try {
if (willPropagateSpyEvents()) {
startedAt = System.currentTimeMillis();
assert null != name;
getSpy().reportSpyEvent(new ActionStartedEvent(name, tracked, parameters));
}
final Transaction transaction = Transaction.begin(this, generateNodeName("Transaction", name), mode, tracker);
try {
result = action.call();
} finally {
Transaction.commit(transaction);
}
if (willPropagateSpyEvents()) {
completed = true;
final long duration = System.currentTimeMillis() - startedAt;
assert null != name;
getSpy().reportSpyEvent(new ActionCompletedEvent(name, tracked, parameters, true, result, null, duration));
}
return result;
} catch (final Throwable e) {
t = e;
throw e;
} finally {
if (willPropagateSpyEvents()) {
if (!completed) {
final long duration = System.currentTimeMillis() - startedAt;
assert null != name;
getSpy().reportSpyEvent(new ActionCompletedEvent(name, tracked, parameters, true, null, t, duration));
}
}
triggerScheduler();
}
}
use of arez.spy.ActionCompletedEvent in project arez by arez.
the class ArezContextTest method action_safeProcedure_throws_Exception.
@Test
public void action_safeProcedure_throws_Exception() throws Exception {
final ArezContext context = new ArezContext();
assertFalse(context.isTransactionActive());
assertThrowsWithMessage(context::getTransaction, "Arez-0117: Attempting to get current transaction but no transaction is active.");
final AccessControlException secException = new AccessControlException("");
final String name = ValueUtil.randomString();
final String param1 = "";
final Object param2 = null;
final int param3 = 3;
final TestSpyEventHandler handler = new TestSpyEventHandler();
context.getSpy().addSpyEventHandler(handler);
final boolean mutation = false;
final SafeProcedure procedure = () -> {
throw secException;
};
assertThrows(AccessControlException.class, () -> context.safeAction(name, mutation, procedure, param1, param2, param3));
assertFalse(context.isTransactionActive());
handler.assertEventCount(4);
{
final ActionStartedEvent e = handler.assertEvent(ActionStartedEvent.class, 0);
assertEquals(e.getName(), name);
assertEquals(e.isTracked(), false);
final Object[] parameters = e.getParameters();
assertEquals(parameters.length, 3);
assertEquals(parameters[0], param1);
assertEquals(parameters[1], param2);
assertEquals(parameters[2], param3);
}
{
final TransactionStartedEvent e = handler.assertEvent(TransactionStartedEvent.class, 1);
assertEquals(e.getName(), name);
assertEquals(e.isMutation(), mutation);
assertEquals(e.getTracker(), null);
}
{
final TransactionCompletedEvent e = handler.assertEvent(TransactionCompletedEvent.class, 2);
assertEquals(e.getName(), name);
assertEquals(e.isMutation(), mutation);
assertEquals(e.getTracker(), null);
}
{
final ActionCompletedEvent e = handler.assertEvent(ActionCompletedEvent.class, 3);
assertEquals(e.getName(), name);
assertEquals(e.getThrowable(), secException);
assertEquals(e.returnsResult(), false);
assertEquals(e.getResult(), null);
assertEquals(e.isTracked(), false);
final Object[] parameters = e.getParameters();
assertEquals(parameters.length, 3);
assertEquals(parameters[0], param1);
assertEquals(parameters[1], param2);
assertEquals(parameters[2], param3);
}
}
use of arez.spy.ActionCompletedEvent in project arez by arez.
the class ArezContextTest method action_procedure_throwsException.
@Test
public void action_procedure_throwsException() throws Throwable {
final ArezContext context = new ArezContext();
assertFalse(context.isTransactionActive());
assertThrowsWithMessage(context::getTransaction, "Arez-0117: Attempting to get current transaction but no transaction is active.");
final String name = ValueUtil.randomString();
final IOException ioException = new IOException();
final String param1 = "";
final Object param2 = null;
final int param3 = 3;
final TestSpyEventHandler handler = new TestSpyEventHandler();
context.getSpy().addSpyEventHandler(handler);
final boolean mutation = false;
final Procedure procedure = () -> {
throw ioException;
};
assertThrows(IOException.class, () -> context.action(name, mutation, procedure, param1, param2, param3));
assertFalse(context.isTransactionActive());
handler.assertEventCount(4);
{
final ActionStartedEvent e = handler.assertEvent(ActionStartedEvent.class, 0);
assertEquals(e.getName(), name);
assertEquals(e.isTracked(), false);
final Object[] parameters = e.getParameters();
assertEquals(parameters.length, 3);
assertEquals(parameters[0], param1);
assertEquals(parameters[1], param2);
assertEquals(parameters[2], param3);
}
{
final TransactionStartedEvent e = handler.assertEvent(TransactionStartedEvent.class, 1);
assertEquals(e.getName(), name);
assertEquals(e.isMutation(), mutation);
assertEquals(e.getTracker(), null);
}
{
final TransactionCompletedEvent e = handler.assertEvent(TransactionCompletedEvent.class, 2);
assertEquals(e.getName(), name);
assertEquals(e.isMutation(), mutation);
assertEquals(e.getTracker(), null);
}
{
final ActionCompletedEvent e = handler.assertEvent(ActionCompletedEvent.class, 3);
assertEquals(e.getName(), name);
assertEquals(e.getThrowable(), ioException);
assertEquals(e.returnsResult(), false);
assertEquals(e.getResult(), null);
assertEquals(e.isTracked(), false);
final Object[] parameters = e.getParameters();
assertEquals(parameters.length, 3);
assertEquals(parameters[0], param1);
assertEquals(parameters[1], param2);
assertEquals(parameters[2], param3);
}
}
use of arez.spy.ActionCompletedEvent in project arez by arez.
the class ArezContextTest method track_function.
@Test
public void track_function() throws Throwable {
final ArezContext context = new ArezContext();
assertFalse(context.isTransactionActive());
final String expectedValue = ValueUtil.randomString();
final AtomicInteger callCount = new AtomicInteger();
final Observer tracker = context.tracker(true, callCount::incrementAndGet);
final Observable<?> observable = newObservable(context);
assertEquals(observable.getObservers().size(), 0);
final int nextNodeId = context.currentNextTransactionId();
final String param1 = "";
final Object param2 = null;
final int param3 = 3;
final TestSpyEventHandler handler = new TestSpyEventHandler();
context.getSpy().addSpyEventHandler(handler);
final String v0 = context.track(tracker, () -> {
assertTrue(context.isTransactionActive());
final Transaction transaction = context.getTransaction();
assertEquals(transaction.getName(), tracker.getName());
assertEquals(transaction.getMode(), tracker.getMode());
assertEquals(observable.getObservers().size(), 0);
assertNotEquals(nextNodeId, observable.getLastTrackerTransactionId());
observable.reportObserved();
// Tracking so state updated
final ArrayList<Observable<?>> observables = transaction.getObservables();
assertNotNull(observables);
assertEquals(observables.size(), 1);
assertEquals(observable.getObservers().size(), 0);
assertEquals(observable.getLastTrackerTransactionId(), nextNodeId);
return expectedValue;
}, param1, param2, param3);
assertFalse(context.isTransactionActive());
context.getSpy().removeSpyEventHandler(handler);
assertEquals(v0, expectedValue);
assertEquals(observable.getLastTrackerTransactionId(), 0);
assertEquals(observable.getObservers().size(), 1);
assertEquals(tracker.getDependencies().size(), 1);
// Reaction not called as the function sets up initial tracking
assertEquals(callCount.get(), 0);
context.action(observable::reportChanged);
assertEquals(callCount.get(), 1);
assertEquals(observable.getObservers().size(), 1);
assertEquals(tracker.getDependencies().size(), 1);
handler.assertEventCount(4);
{
final ActionStartedEvent e = handler.assertEvent(ActionStartedEvent.class, 0);
assertEquals(e.isTracked(), true);
final Object[] parameters = e.getParameters();
assertEquals(parameters.length, 3);
assertEquals(parameters[0], param1);
assertEquals(parameters[1], param2);
assertEquals(parameters[2], param3);
}
{
final TransactionStartedEvent e = handler.assertEvent(TransactionStartedEvent.class, 1);
assertEquals(e.isMutation(), true);
final ObserverInfo info = e.getTracker();
assertNotNull(info);
assertEquals(info.getName(), tracker.getName());
}
{
final TransactionCompletedEvent e = handler.assertEvent(TransactionCompletedEvent.class, 2);
assertEquals(e.isMutation(), true);
final ObserverInfo info = e.getTracker();
assertNotNull(info);
assertEquals(info.getName(), tracker.getName());
}
{
final ActionCompletedEvent e = handler.assertEvent(ActionCompletedEvent.class, 3);
assertEquals(e.getThrowable(), null);
assertEquals(e.returnsResult(), true);
assertEquals(e.getResult(), v0);
assertEquals(e.isTracked(), true);
final Object[] parameters = e.getParameters();
assertEquals(parameters.length, 3);
assertEquals(parameters[0], param1);
assertEquals(parameters[1], param2);
assertEquals(parameters[2], param3);
}
}
use of arez.spy.ActionCompletedEvent in project arez by arez.
the class ArezContextTest method action_function_throwsException.
@Test
public void action_function_throwsException() throws Throwable {
final ArezContext context = new ArezContext();
assertFalse(context.isTransactionActive());
assertThrowsWithMessage(context::getTransaction, "Arez-0117: Attempting to get current transaction but no transaction is active.");
final String name = ValueUtil.randomString();
final IOException ioException = new IOException();
final String param1 = "";
final Object param2 = null;
final int param3 = 3;
final TestSpyEventHandler handler = new TestSpyEventHandler();
context.getSpy().addSpyEventHandler(handler);
final boolean mutation = false;
assertThrows(IOException.class, () -> context.action(name, mutation, () -> {
throw ioException;
}, param1, param2, param3));
assertFalse(context.isTransactionActive());
handler.assertEventCount(4);
{
final ActionStartedEvent e = handler.assertEvent(ActionStartedEvent.class, 0);
assertEquals(e.getName(), name);
assertEquals(e.isTracked(), false);
final Object[] parameters = e.getParameters();
assertEquals(parameters.length, 3);
assertEquals(parameters[0], param1);
assertEquals(parameters[1], param2);
assertEquals(parameters[2], param3);
}
{
final TransactionStartedEvent e = handler.assertEvent(TransactionStartedEvent.class, 1);
assertEquals(e.getName(), name);
assertEquals(e.isMutation(), mutation);
assertEquals(e.getTracker(), null);
}
{
final TransactionCompletedEvent e = handler.assertEvent(TransactionCompletedEvent.class, 2);
assertEquals(e.getName(), name);
assertEquals(e.isMutation(), mutation);
assertEquals(e.getTracker(), null);
}
{
final ActionCompletedEvent e = handler.assertEvent(ActionCompletedEvent.class, 3);
assertEquals(e.getName(), name);
assertEquals(e.getThrowable(), ioException);
assertEquals(e.returnsResult(), true);
assertEquals(e.getResult(), null);
assertEquals(e.isTracked(), false);
final Object[] parameters = e.getParameters();
assertEquals(parameters.length, 3);
assertEquals(parameters[0], param1);
assertEquals(parameters[1], param2);
assertEquals(parameters[2], param3);
}
}
Aggregations