Work with asynchronous control structures (Free interface?)

The initialization code for our Flex application runs a series of asynchronous calls to verify user credentials, load external data, connect to a JMS theme, etc. Depending on the context in which the application is running, some of these calls are not made or are made with different parameters.

Because all of these calls occur asynchronously, the code that manages them is difficult to read, understand, maintain, and test. For each call, we need to have some callback mechanism in which we decide which call to make next.

I was wondering if anyone had experimented with wrapping these calls in executable modules and had a Fluent Interface (FI) that could connect and manage them.

From the top of my head, the code might look something like this:

var asyncChain:AsyncChain = execute(LoadSystemSettings) .execute(LoadAppContext) .if(IsAutologin) .execute(AutoLogin) .else() .execute(ShowLoginScreen) .etc; asyncChain.execute(); 

AsyncChain will be the execution tree, we will build using FI (and we could, of course, also build one without FI).

This might be an interesting idea for environments that work in the same stream model, such as Flash Player, Silverlight, JavaFX?, ...

Before diving into the code to try everything, I was hoping to get some feedback.


Update 03/19/2010 . We created an experimental Task API in a Spring ActionScript project that provides control over async processes. We will be happy to receive feedback. http://www.springactionscript.org/docs/reference/html/the_operation_api.html#tasks

+4
source share
5 answers

I did something similar, especially to initialize applications. However, I wrote this using MXML, since we are developing most of our flash applications using Flex.

The syntax looks just like an array declaration (I just compose the tags, but you get the idea):

 <Initialize> <DisplayPreloader /> <LoadConfiguration id="configurationLoader" source="foo.xml" /> <ParseConfiguration source="{configurationLoader.result}" /> <!-- ... ---> </Initialize> 

Using interfaces like IMXMLObject, it works well enough to just click it in the application, and hey presto, there is an initialization code. Of course, this should not be for initialization, it can be applied anywhere.

Famous pros:

  • The execution order is intuitive and easy to change (just move the tag up or down)
  • The steps on the list really don't care about the other steps.
  • Data can be transferred between steps using binding syntax, promote dependency injection
  • Properly encapsulated single task steps can be easily reused.

Known cons:

+2
source

You can definitely do this. You can transfer actions and continuation functions and threaten them with an asynchronous call and a callback. This is called Continuation Walking Style . This will require the conversion of ordinary logic into a sequence of function calls.

An easy way would be to introduce some kind of monadic structure ( like in Haskell ) that will encapsulate your asynchronous calls. But you still have to create several functions (callbacks) when converting your program logic to CPS. See: CPS in Haskell . But the syntax is ugly. Good syntax is provided in Scheme, but it is closely related to the computational model of Scheme: macros and library code available for macro processing.

With some language support, you can simplify the syntax: an example is expressions of calculations in F #, exactly async one . Under the hood is close relative to the concept of the Monad.

Another interesting idea for high-level programming is implemented in Reactive Extensions for.NET (Rx) . The idea is quite simple: events are very similar to lists. The difference is that you do not create them (push-based collection), but rather get the next element from them (pull-based assembly). Invert the interface accordingly: instead of MoveNext and Current in IEnumerator, you get OnNext, OnDone, and OnError in IObservable. Then, combining the existing observables, you can get something close to the code that you suggested.

+1
source

If you use Flex and have an idea of ​​the asynchronous call flow, I would use the archetypal Mate structure. According to Api: β€œThe main part of Mate is the EventMap tag, which allows you to define mappings for events generated by your application. This is basically a list of IActionList blocks, where each block corresponds to the type of event [..]" Now in each EventMap you You can have several asynchronous server calls that are logically connected to each other. In general, this is an mxml tag, so it is also very easy to read.

+1
source

since your functions must be asynchronous, you cannot force them to block until the next action, so all they do is copy some codes into a structure that will be executed later.

Sounds familiar? In short, you compile a language and run a virtual machine.

nothing wrong with that, but thinking in the right terms will allow you to search for the right literature. for example, instead of fighting your internal structure, so the .else() knows which .if() it connects to, just write a full parser and send it a line with your program.

there are also many examples of writing simple virtual machines

0
source

Most of this very interesting discussion of this type of programming. It is also the weakest part of our most common languages, and it is very painful to express asynchronous logic in a synchronous language. I believe that the continuation here is the answer, because we can easily perceive the synchronous and programmatic synchronous, but simple asynchronous program control flow. Synchronous programming is very well understood, and reuse is very simple. Asinks not at all. But until the world catches up ... alas.

What you offer looks interesting, but I did it now at least twice and was never happy with it. I think you will have a hard time evaluating your if blocks at runtime. The problem that I always encountered was to get the data from one step to another in its purest form. How are you going to write an if statement with respect to values ​​that may be missing until the step is completed.

If I were you, I would consider a state template. The state model models this type of behavior in objects, and transitions can be performed asynchronously. You could create a Fluent interface to create states like you above.

I would be very interested to know how this happens when I do this in my AIR application now, and I'm just happy with it.

0
source

Source: https://habr.com/ru/post/1285682/


All Articles