How to trigger the execution of the compensation flow for the activities used within an Automatonymous state machine? - masstransit

My activities throw exceptions from time to time during the execution, so I've implemented the Faulted methods of Activity<TInstance> to handle that, discarding the changes made in the Execute method. I thought that there's some wiring underneath in Automatonymous that makes it so that the Faulted method executes when the Execute method throws an exception and then calls the Faulted methods for the activities that were executed already. It turns out that there's no such thing, as my Faulted methods are never executed.
Should I call those myself in a try/catch block instead? I could produce the BehaviorExceptionContextProxy based on BehaviorContext and the exception thrown. The only next Behavior I could pass would be the one inserted into that Activity's Execute method, but logically that means I'm compensating in the wrong direction as that next Behavior is actually to be executed after this one succeeds, so I'd compensate too much.
I also tried to use the Catch in the state machine, which does handle the exception, however, I couldn't find any way to start the execution of the compensation flow for the activity that failed when I only have the ExceptionActivityBinder present.
Is there any good way to trigger the compensation flow of the activities?

An activity within a state machine (using Automatonymous) is much different than an activity within Courier. Unfortunately, they both have the same name, which can create confusion.
When an activity throws an exception, the Faulted method of the next activity in the behavior is called. If that method is a regular activity method (such as .Then, .Publish, etc.) it is skipped, since the Faulted method of those activities just calls the next activity in the behavior.
A Catch activity, however, can be used to catch the exception and execute a rescue behavior (which is a sequence of activities).
Either way, the Faulted method of the activity which throws an exception within the Execute method is not called. So yes, you should use a try/catch, but allow the exception to flow back out of the Execute method so that the behavior handles it properly.

Related

Is there a way to execute the compensation from faulted activity

Lets assume I have defined the routing slip activity. Within Execute method I would like to make several asynchronous service calls. Lets assume 3 service calls. Two of them succeed and one fails. Then I would like to execute compensate action of this activity in order to compensate the changes introduced by two succeeded service calls. From what I see the compensation only runs for previous activities, the current activity compensation has no chance to be invoked when there is exception somewhere in it. Is there a way to deal with it or I should change the approach?
I would like to achive sth similar to
using MassTransit.
You should have three separate activities, and execute them in order, so that as they succeed individually, they are added to the log. If an activity fails, the previous activities will be compensated.
By having all three calls in a single activity, you're going against the entire reason for having the routing slip and activities.

How to attach uncaught exception handler/completion to CompletableFuture chain

The use-case:
an exception occurs during CompletableFuture chain
none of exceptionally, whenComplete or handle method is attached to that CompletableFuture chain
The result:
The exception is never caught and there's no tracking/log of it. Which in case of Async systems is 1) undesirable and 2) an indicator for hard and hidden problems (such as NPE, Runtime Exc, etc.) to spot.
The question:
Is it feasible to implement CompletableFuture.UncaughtExceptionHandler mechanism by analogy / in a similar manner with java.lang.Thread.UncaughtExceptionHandler? The idea is to provide [default] uncaught exception handler/completion to be called if the CompletableFuture chain does not have java.util.concurrent.CompletableFuture.UniExceptionally Completion attached.
The simple answer is: no.
However, someone posted an ugly hack to get similar behavior in another thread:
How to handle uncaught exceptions from CompletableFuture.runAsync
I for one escape this problem by using ReactiveX (http://reactivex.io), but that choice might be beyond your control. In that case, you could consider creating a wrapped class for CompletableFuture that always registers an exception handler behind the scenes, so you don't have to explicitely call exceptionally(..) any more. But again, this is just a work-around.

Waiting for task throws

I'm just starting out with WinRT's concurrency model. I have a task that I need to wait on, but calling wait() throws an exception that I can't catch.
Simplest possible code:
concurrency::task<StorageFile^> getFileTask = concurrency::create_task(Windows::Storage::ApplicationData::Current->LocalFolder->GetFileAsync(fileString));
getFileTask.wait();
The exception it throws is:
Microsoft C++ exception: Concurrency::invalid_operation at memory location 0x0402C45C
How do I set this up so that it works?
One of the most important rules that you must follow when building a Windows Store app is that you must never block the UI thread. Never ever.
If you start an asynchronous operation, you get a future or task that "owns" that operation. If you call get() or wait() on that operation before the asynchronous operation has completed, that call will block until the operation completes, then it will return the result.
Since blocking the UI thread is bad, if you attempt to synchronize with a not-yet-completed asynchronous operation on the UI thread, the call to get() or wait() will throw, to prevent the UI thread from being blocked. This exception is there to help you to remember not to block the UI thread. :-)
You should use task's then() to provide a continuation that will run when the asynchronous operation completes. If the continuation needs to run on the UI thread as well, be sure to pass task_continuation_context::use_current() to then() to ensure that the continuation is marshaled back to the UI thread for execution.
Note: This exception is only thrown if you are using C++/CX. If you are using C++ without the C++/CX language extensions, the call to get() or wait() will successfully block, potentially resulting in a poor user experience. In general, C++/CX has many more "guard rail" features like this one that are designed to make it easier for you to write good code. When using C++/CX, you get the full power of C++, with the understanding that there are more opportunities for error.

Handle an event raised from background thread

I developed a class (in C#) for sending and receiving messages over network. It creates a new thread (listener thread) which waits till a new message arrives then raises an event.
The problem is the event is raised in the listener thread and when I want to use this class in a wpf application, a run-time error occurs trying to handle the event
The error is:The calling thread cannot access this object because a different thread owns it.
Is there any proper way to deal with this situation when the event raises in the mentioned class?
You've got to be on the UI thread to update UI objects. You can use the window's Dispatcher to execute code there:
this.Dispatcher.Invoke(new Action(() =>
{
// Code that updates UI here
}));
BackgroundWorker explicitly supports marshaling to the UI thread. You have to use it though, call its ReportProgress() method. While optimized for reporting progress, you don't have to use it for that. There's an overload that accepts an object, you can pass anything you want. The event handler gets it as the e.UserState value. From there, you could use that object directly or use it to re-raise another set of events.
Do beware thread-safety requirements for that object. The worker keeps running and is not in any way synchronized with the execution of the ProgressChanged event handler. So it should no longer update the object. Best to create a new instance of it after calling ReportProgress().

I Need an Analogy: Triggers and Events

For another question, I'm running into a misconception that seems to arise here at SO occasionally. Some questioners seem to think that Triggers are to Databases as Events are to OOP.
Does anyone have a good analogy to explain why this is a flawed comparison, and the consequences of misapplying it?
EDIT:
Bill K. has hit it correctly, but maybe doesn't see the importance of the critical differeence between the event and the callback function that strikes me, anyway. Triggers actually cause code to execute every time the event occurs; callbacks only occur whenever one has been registered for an event (which is not true for the vast majority of events); and even then, in most cases the callback's first action is to deregister itself (or at least the callback contains a qualifcation exit so it only executes once.)
If you write a trigger, it will unfailingly execute every time the event occurs, because there's no way to register or deregister to code segment.
Triggers are a way to interpose repeating logic synchronously into the thread of execution (i.e. synchronicity). Events are a means to defer logic until later (i.e. implement asynchronicity).
There are exceptions and mitigations in both cases, but the basic patterns of triggers and callbacks are mostly opposite in intention and implementation. Often the distinction doesn't seem to have fully sunk in. (IMHO, YMMV). :D
They're not the same thing, but they're not unrelated.
In both cases, the mechanism can be described approximately as follows:
Some block of code declares "interest" for changes in state.
Your application affects some change.
The system runs the block of code in response to the change.
Perhaps a database trigger is more like a callback function that has registered interest in a specific event.
Here's an analogy: the event is a rubber ball that you throw. The trigger is a dog that chases after a thrown ball.
If there's some other difference that you have in mind that makes it "dangerous" (note: OP has edited this choice of word out of the question) to compare triggers and events, you can describe what you mean.
Triggers are a way to interpose
repeating logic synchronously into the
thread of execution (i.e.
synchronicity). Events are a means to
defer logic until later (i.e.
implement asynchronicity).
Okay, I see what you mean more clearly. But I think it's in some ways subject to the implementation. I wouldn't assume an event handler has to deregister itself; it depends on the system you're using. A UNIX signal handler, for example, has to prevent itself from catching a new signal while it's already handling one. But a Java servlet inside a Tomcat container should be thread-safe because it may be called concurrently by multiple threads. They're both event handlers, of different kinds.
Event handlers may be synchronous or asynchronous. Can a handler in a publish/subscribe system read messages that were posted recently, but prior to the handler registering its interest? Or only messages posted concurrently?
There's another important reason to treat triggers as different from event handlers: I frequently recommend against doing anything in a trigger that affects state outside the database.
For example, sending an email, writing to a file, posting to a web service, or forking a process is inappropriate inside a trigger. If for no other reason than the transaction that spawned the trigger may be rolled back, but you can't roll back those external effects. You may not even be using explicit transactions, but say you send an email in a BEFORE trigger, but the operation fails because of a NOT NULL constraint or something.
Instead, all such work should be done by code in one's application, after one has confirmed that the SQL operation was successful and the transaction committed.
It's too bad that people keep trying to do inappropriate work inside a trigger. There are senior developers at MySQL who promote UDFs to read and write data in memcached. Wow -- I just noticed these have made it into the MySQL 6.0 product!! Shocking!
So here's another attempt at an analogy, comparing triggers and events to the process of a criminal trial:
A BEFORE trigger is an allegation.
An AFTER trigger is an indictment.
COMMIT is a conviction after a guilty verdict.
ROLLBACK is an acquittal after an innocent verdict.
You only want to put the perpetrator in prison after they are convicted.
Whereas an EVENT is the crime itself.

Resources