Program flow, blocking and non-blocking


#1

Program flow

By default, Redtamarin programs are blocking (synchronous), that means
unlesss you tell the program to wait it will continue its flow to the end,
and when there is no more code to be executed it will terminate.

blocking flow

start
  |
  |
  V
 end
  |
  V
program exit

Most command-line (CLI) programs are like that, many server-side programming languages too
like Perl, PHP, Python, etc.


You can make Redtamarin programs non-blocking (asynchronous)
by invoking Runtime.goAsync() anywhere in your code,
but then, when the program reach the end, it will wait forever
unless you explicitly tell it to end.

non-blocking flow

start
  |
  |
  V
 loop forever
  |
  V
exit never reached

This “forever loop” is what is called a busy wait loop,
it is usually avoided because it then increase the CPU usage to 100%,
but the way we do it is we sleep within the loop which allow to free up the CPU.

By default, the sleep interval is 1000 milliseconds (or 1 second)
which keep the CPU usage around 0,1%.

Most GUI applications are like that, they will wait for events, user interactions, etc.
unless you specifically tell them to stop or exit or close or terminate, they will run forever.

Programs running in the Flash Player and Adobe AIR are like that too.

One of the greatest challenge of Redtamarin is to allow one (blocking) or the other (non-blocking)
without having everything explode into your hands :stuck_out_tongue:

Even if CLI programs are mainly blocking, there are many use cases where you want them non-blocking:

  • a server
    anything really that use sockets and wait for clients to connect
    to then send them back data want to “loop forever”

  • a daemon / background service
    those programs are meant to run forever and even restart themselves if they crash

And same you can find GUI programs that will act as blocking:

  • automation tool
    that need to run a GUI, execute a serie of commands to it and then close it
  • alert/notification tools
    the GUI is shown only at a specific time and then close
  • etc.

Blocking functions

A blocking function is a function that can completely
block the flow of the program.

The best example is the sleep() function, anywhere you could
say “sleep 2 days” for example, and it will just wait there.

But technically all ActionScript 3 functions are like that,
you have to wait for the function to return before going to the next task.

Now, the problem is when you combine a blocking function with the different program flows.

blocking flow

start
  |
  <-- blocking function that blocks forever
  |
  V
program exit (never reached)

Anything from after the blocking function to the end of the program
will not be executed.


non-blocking flow

start
  |
  <-- blocking function
  |
  V
 loop forever (never reached)
  |     |
  |      \ async signals, timers, events never received
  V
exit never reached

Anything from after the blocking function to the loop
will not be executed, and worst anything asynchronous
handled within the loop will not be caught.

Compared to Flash and Adobe AIR,
code executed in Redtamarin can sleep forever,
you will not get a timeout error (you can in specific case)

It is a good thing because it allow us to implement
something like Runtime.goAsync() to loop forever
at the very end of the program.

But it is also dangerous as it does not work well
with non-blocking or asynchronous flow.


Events

Redtamarin provide a simple implementation of an EventDispatcher class
see shell.events.BasicEventDispatcher

which is then used for the implementation of flash.events.EventDispatcher

That means you can use AS3 events as you would do in Flash or Adobe AIR.

But not all events are equals, so here few more details.

You can have synchronous events and asynchronous events,
here the differences:

  • synchronous events
    those are the “regular” events where you can use the IEventDispatcher methods
    to addEventListener() / removeEventListener() / dispatchEvent()
    between different object instances from your own code definitions
    we consider them synchronous because the event call is generated
    from user defined objects, eg. the user code control when the event is dispatched
    it is predictable

  • asynchronous events
    they are working on the exact same principles as the synchronous events
    with the crucial difference that the system control when the events are dispatched
    eg. the control is external to user code
    it is not predictable
    this “external” or “system” control can be such things as:

    • time
    • system “events” (signals)
    • file I/O
    • socket I/O
    • etc.

The good news is you don’t need to use Runtime.goAsync() each time you want to use events,
but you do have to use Runtime.goAsync() when asynchronous events are involved.

One of the best use case is the TimerEvent, because you don’t control time (the system does)
if you listen for a TimerEvent without Runtime.goAsync(), your program flow will probably
terminate before it get the chance to receive such event.

In summary, you have to use Runtime.goAsync() if you wait for events coming out of the system,
otherwise the default blocking nature of the program flow will end the program.


Synchronous vs Asynchronous

Simply put, synchronous is what requires synchronisation, it is what needs a coordination of events to operate, it is a sequential form of data processing which can not permits another processing to start before a previous one terminate.

And so at the opposite, asynchronous does not need to be synchronised or coordinated, it is a non-sequential form of data processing which permits other processing to continue before a previous execution has finished.

By default, all ActionScript code is synchronous (or blocking).

Simplest example are basic functions, you need to wait for the function to execute all its code before you can move on to the next function, and on, and on.

It’s clearly explained here

ActionScript: The Definitive Guide
Chapter 10. Events and Event Handlers

10.1. Synchronous Code Execution

As a movie plays, the timeline’s playhead travels from frame to frame. Each time the playhead enters a new frame, the interpreter executes any code attached to that frame. After the code on a frame has been executed, the screen display is updated and sounds are played. Then, the playhead proceeds to the next frame.

For example, when we place code directly on frame 1 of a movie, that code executes before the content in frame 1 is displayed. If we place another block of code on a keyframe at frame 5 of the same movie, frames 1 through 4 will be displayed, then the code on frame 5 will be executed, then frame 5 will be displayed. The code executed on frames 1 and 5 is said to be executed synchronously because it happens in a linear, predictable fashion.

All code attached to the frames of a movie is executed synchronously. Even if some frames are played out of order due to a gotoAndPlay( ) or gotoAndStop( ) command, the code on each frame is executed in a predictable sequence, synchronized with the movement of the playhead.

and most people will then conclude that the ActionScript 3 event system is then synchronous
eg. you can predict the order of execution of the code and also the order of execution of events


Let’s say it is partly true, but not-only, you also have this other little nugget

10.2. Event-Based Asynchronous Code Execution

Some code does not execute in a predictable sequence. Instead, it executes when the ActionScript interpreter notices that one of a predetermined set of events has occurred. Many events involve some action by the user, such as clicking the mouse or pressing a key. Just as the playhead entering a new frame executes synchronous code attached to the frame, events can cause event-based code to execute. Event-based code (code that executes in response to an event) is said to be executed asynchronously because the triggering of events can occur at arbitrary times.

Synchronous programming requires us to dictate, in advance, the timing of our code’s execution. Asynchronous programming, on the other hand, gives us the ability to react dynamically to events as they occur. Asynchronous code execution is critical to ActionScript and to interactivity itself.

This chapter explores asynchronous (event-based) programming in Flash and catalogs the different events supported by ActionScript.

I would say it is safer to consider the ActionScript 3 event system as asynchronous,
but not necessarily for all type of events.

Simply put, anything you can not predict is injecting asynchronicity into the system of events.


So what are we? Synchronous or Asynchronous?
well… we can be both but not at the same time.

We need to alternate chunk of synchronous code interrupted by asynchronous code.

More exactly, we should see everything as synchronous code which on a regular interval
will check if something asynchronous happened.

That’s like the explanation we have seen before

As a movie plays, the timeline’s playhead travels from frame to frame. Each time the playhead enters a new frame, the interpreter executes any code attached to that frame. After the code on a frame has been executed, the screen display is updated and sounds are played. Then, the playhead proceeds to the next frame.

but here let’s replace the last part

As a movie plays, the timeline’s playhead travels from frame to frame. Each time the playhead enters a new frame, the interpreter executes any code attached to that frame. After the code on a frame has been executed, we check if asynchronous events occurred.


In summary and relative to Redtamarin, we are blocking (synchronous) by default,
to prevent the program to exit you will have to explicitly tell it to wait.

We can activate a non-blocking (asynchronous) mode, but then in this case
the program will never exit and so to terminate you will have to explicitly tell it to stop.


Cracking Up The Event Loop