[Vala] Documenting 'async' / WAS: Further speculations on couroutines, generators and threads : Emulating Go's goroutines and channels in Vala



Alexandre Rosenfeld wrote:
Async methods were created primarily for GIO to do non-blocking
IO. Doing IO usually blocks the application and so freezes the UI,
so the GLib answer is to provide callbacks to be called when the IO
is done and the program can keep executing while IO is done in the
background (note here that background does not necessarily mean
another thread, the IO can be done by the kernel and notify the
process when it's complete).

Async methods have nothing to do with threads, so none of these
points are valid. However, what async methods allow is to stop the
processing of a function in the middle and resume it after the async
method returns, by the means of the callbacks. So, what the async
method can do is spawn a thread to do background processing and
later call the callback to resume the operation of the method that
called it.

Which means async methods can be just as blocking as any other
method if it does sequential processing and at the end calls the
callback. But also means it can be designed to use any other way to
provide background processing (including threads) without blocking
the main program (especially the UI) and thus can take advantage of
multiple cores.

This is helpful, thanks.

There seems to be special stuff associated with an async method which
I haven't found documented well anywhere.  For async method 'method',
there are all these ways to use it:

- Call 'method' from non-async code, starts it running until its first
  'yield', at which point it returns to the caller.  (Correct?)

    method(args);

- Get callback (from within method itself).  This is the callback to
  resume execution after the following 'yield'.  (Correct?)

    SourceFunc callback = method.callback;

- Use the resume callback from elsewhere.  'method' resumes and takes
  control again, running until its next 'yield', at which point it
  returns from this call.  (Correct?)

    callback();

- Give up control and return to the caller.  This doesn't guarantee in
  any way that the method will be resumed, i.e. callback() must be
  called somewhere else.  (Correct?)

    yield;

- Give up control but arrange for a resume callback when idle.  This
  requires the main loop to be running.  (Correct?)

    Idle.add(method.callback);
    yield;

- Call async method 'other_method' from 'method'.  This automatically
  sets up a callback for 'method' to resume itself and collect the
  return value when 'other_method' completes.  (Correct?)
  
    yield other_method(args);

  Question: At the C level, I guess this first calls forwards to
  'other_method' to start it before returning to the caller due to the
  'yield'.  If the 'other_method' also yields, then there is no
  problem, but if 'other_method' finishes without yielding (e.g. if it
  can return the result right away without doing any asynchronous
  work), then the 'method' callback would be called again, only a few
  stack frames lower.  In theory if 'method' called 'other_method'
  repeatedly like this, the stack could overflow.  Is this correct?
  If so maybe that needs documenting.

- Call with .begin().  Question: Is this just like the 'method()' call
  but adding a callback request for when method() finishes?  If so
  will it also just run until the first 'yield' and then return?

    method.begin(args, callback);

- Call with .end().  For use within the 'begin' callback, to get
  method return value and clean up.  Question: Is an .end() call
  required for plain 'method()' style invocation?

    method.end(out_args);

Also, questions:

- Are there any other special features associated with async methods?
  (Any other .<identifier> features, for example.)

- When it is necessary to have a main loop running?  Some of the
  generated C code requests an idle callback.  I guess this won't work
  without a main loop running.  But the Generator, for example, seems
  to run through fine without a main loop.

- The docs say "The .callback call is used to implicitly register a
  _finish method for the async method".  What does this mean?  Also:
  "end() is a syntax for the *_finish method".  I'm confused.

If someone can say RIGHT or WRONG to some of the points in this list
I'd be happy to document this on the wiki somewhere.

Jim

-- 
 Jim Peters                  (_)/=\~/_(_)                 jim uazu net
                          (_)  /=\  ~/_  (_)
 UazĂș                  (_)    /=\    ~/_    (_)                http://
 in Peru            (_) ____ /=\ ____ ~/_ ____ (_)            uazu.net



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]