<commit_before>Progress Reporting
------------------

This document describes the design and use cases for the progress reporting
messages.

PROGRESS messages are posted on the bus to inform the application about the
progress of asynchonous operations in the pipeline. This should not be confused
with asynchronous state changes.

We accomodate for the following requirements:

 - Application is informed when an async operation starts and completes.
 - It should be possible for the application to generically detect common
   operations and incorporate their progress into the GUI.
 - Applications can cancel pending operations by doing regular state changes.
 - Applications should be abe able to wait for completion of async operations.

We allow for the following scenarios:

 - Elements want to inform the application about asynchronous DNS lookups and
   pending network requests. This includes starting and completing the lookup.
 - Elements opening devices and resources assynchronously.
 - Applications having more freedom to implement timeout and cancelation of
   operations that currently block the state changes or happen invisibly behind
   the scenes.


Rationale
~~~~~~~~~

The main reason for adding these extra progress notifications is twofold: 

 1) to give the application more information of what is going on 

    When there are well defined progress information codes, applications
    can let the user know about the status of the progress. We anticipate to
    have at least DNS resolving and server connections and requests be well
    defined.

 2) To make the state changes non-blocking and cancelable.

    Currently state changes such as going to the READY or PAUSED state often do
    blocking calls such as resolving DNS or connecting to a remote server. These
    operations often block the main thread and are often not cancelable, causing
    application lockups.

    We would like to make the state change function, instead, start a separate
    thread that performs the blocking operations in a cancelable way. When going
    back to the NULL state, all pending operations would be canceled immediately.
    
    For downward state changes, we want to let the application implement its own
    timeout mechanism. For example: when stopping an RTSP stream, the clients
    needs to send a TEARDOWN request to the server. This can however take an
    unlimited amount of time in case of network problems. We want to give the
    application an opportunity to wait (and timeout) for the completion of the
    async operation before setting the element to the final NULL state.

Progress updates are very similar to buffering messages in the same way that the
application can decide to wait for the completion of the buffering process
before performing the next state change. It might make sense to implement
buffering with the progress messages in the future.


Async state changes
~~~~~~~~~~~~~~~~~~~

GStreamer currently has a GST_STATE_CHANGE_ASYNC return value to note to the
application that a state change is happening assynchronously. 

The main purpose of this return value is to make the pipeline wait for preroll
and delay a future (upwards) state changes until the sinks are prerolled.

In the case of async operations on source, this will automatically force sinks
to stay async because they will not preroll before the source can produce data.

The fact that other asynchonous operations happen behind the scnes is irrelevant
for the prerolling process so it is not implemented with the ASYNC state change
return value in order to not complicate the state changes and mix concepts.


Use cases
~~~~~~~~~
 
 * RTSP client (but also HTTP, MMS, ...)

  When the client goes from the READY to the PAUSED state, it opens a socket,
  performs a DNS lookup, retieves the SDP and negotiates the streams. All these
  operations currently block the state change function for an undefinite amount
  of time and while they are blocking cannot be canceled.

  Instead, a thread would be started to perform these operations assynchronously
  and the state change would complete with the usual NO_PREROLL return value.
  Before starting the thread a PROGRESS message would be posted to mark the
  start of the async operation.

  As the DNS lookup completes and the connection is established, PROGRESS messages
  are posted on the bus to inform the application of the progress. When
  something fails, an error is posted and a PROGRESS CANCELED message is posted.
  The application can then stop the pipeline.

  If there are no errors and the setup of the streams completed successfully, a
  PROGRESS COMPLETED is posted on the bus. The thread then goes to sleep and the
  assynchronous operation completed.

  The RTSP protocol requires to send a TEARDOWN request to the server
  before closing the connection and destroying the socket. A state change to the
  READY state will issue the TEARDOWN request in the background and notify the
  application of this pending request with a PROGRESS message.

  The application might want to only go to the NULL state after it got confirmation
  that the TEARDOWN request completed or it might choose to go to NULL after a
  timeout. It might also be possible that the application just want to close the
  socket as fast as possible without waiting for completion of the TEARDOWN request.

 * Network performance measuring

  DNS lookup and connection times can be measured by calculating the elapsed
  time between the various PROGRESS messages.
  


Messages
~~~~~~~~

 A new PROGRESS message will be created.
 The following fields will be contained in the message:

  - "type", GST_TYPE_PROGRESS_TYPE

      - a set of types to define the type of progress

        GST_PROGRESS_TYPE_START: A new task is started in the background
        GST_PROGRESS_TYPE_CONTINUE: The previous tasks completed and a new
                  one continues. This is done so that the application can follow
                  a set of continuous tasks and react to COMPLETE only when the
                  element completely finished.
        GST_PROGRESS_TYPE_CANCELED: A task is canceled by the user.
        GST_PROGRESS_TYPE_ERROR: A task stopped because of an error. In case of
                  an error, an error message will have been posted before.
        GST_PROGRESS_TYPE_COMPLETE: A task completed successfully.

  - "code", G_TYPE_STRING

     A generic extensible string that can be used to programatically determine the
     action that is in progress. Some standard predefined codes will be
     defined.

  - "text", G_TYPE_STRING

     A user visible string detailing the action.

  - "percent", G_TYPE_INT  between 0 and 100

    Progress of the action as a percentage, the following values are allowed:
      - GST_PROGRESS_TYPE_START always has a 0% value.
      - GST_PROGRESS_TYPE_CONTINUE have a value between 0 and 100
      - GST_PROGRESS_TYPE_CANCELED, GST_PROGRESS_TYPE_ERROR and
        GST_PROGRESS_TYPE_COMPLETE always have a 100% value.

  - ....

     Depending on the code, more fields can be put here.
<commit_msg>design: mention timeout in the progress message<commit_after>Progress Reporting
------------------

This document describes the design and use cases for the progress reporting
messages.

PROGRESS messages are posted on the bus to inform the application about the
progress of asynchonous operations in the pipeline. This should not be confused
with asynchronous state changes.

We accomodate for the following requirements:

 - Application is informed when an async operation starts and completes.
 - It should be possible for the application to generically detect common
   operations and incorporate their progress into the GUI.
 - Applications can cancel pending operations by doing regular state changes.
 - Applications should be abe able to wait for completion of async operations.

We allow for the following scenarios:

 - Elements want to inform the application about asynchronous DNS lookups and
   pending network requests. This includes starting and completing the lookup.
 - Elements opening devices and resources assynchronously.
 - Applications having more freedom to implement timeout and cancelation of
   operations that currently block the state changes or happen invisibly behind
   the scenes.


Rationale
~~~~~~~~~

The main reason for adding these extra progress notifications is twofold: 

 1) to give the application more information of what is going on 

    When there are well defined progress information codes, applications
    can let the user know about the status of the progress. We anticipate to
    have at least DNS resolving and server connections and requests be well
    defined.

 2) To make the state changes non-blocking and cancelable.

    Currently state changes such as going to the READY or PAUSED state often do
    blocking calls such as resolving DNS or connecting to a remote server. These
    operations often block the main thread and are often not cancelable, causing
    application lockups.

    We would like to make the state change function, instead, start a separate
    thread that performs the blocking operations in a cancelable way. When going
    back to the NULL state, all pending operations would be canceled immediately.
    
    For downward state changes, we want to let the application implement its own
    timeout mechanism. For example: when stopping an RTSP stream, the clients
    needs to send a TEARDOWN request to the server. This can however take an
    unlimited amount of time in case of network problems. We want to give the
    application an opportunity to wait (and timeout) for the completion of the
    async operation before setting the element to the final NULL state.

Progress updates are very similar to buffering messages in the same way that the
application can decide to wait for the completion of the buffering process
before performing the next state change. It might make sense to implement
buffering with the progress messages in the future.


Async state changes
~~~~~~~~~~~~~~~~~~~

GStreamer currently has a GST_STATE_CHANGE_ASYNC return value to note to the
application that a state change is happening assynchronously. 

The main purpose of this return value is to make the pipeline wait for preroll
and delay a future (upwards) state changes until the sinks are prerolled.

In the case of async operations on source, this will automatically force sinks
to stay async because they will not preroll before the source can produce data.

The fact that other asynchonous operations happen behind the scnes is irrelevant
for the prerolling process so it is not implemented with the ASYNC state change
return value in order to not complicate the state changes and mix concepts.


Use cases
~~~~~~~~~
 
 * RTSP client (but also HTTP, MMS, ...)

  When the client goes from the READY to the PAUSED state, it opens a socket,
  performs a DNS lookup, retieves the SDP and negotiates the streams. All these
  operations currently block the state change function for an undefinite amount
  of time and while they are blocking cannot be canceled.

  Instead, a thread would be started to perform these operations assynchronously
  and the state change would complete with the usual NO_PREROLL return value.
  Before starting the thread a PROGRESS message would be posted to mark the
  start of the async operation.

  As the DNS lookup completes and the connection is established, PROGRESS messages
  are posted on the bus to inform the application of the progress. When
  something fails, an error is posted and a PROGRESS CANCELED message is posted.
  The application can then stop the pipeline.

  If there are no errors and the setup of the streams completed successfully, a
  PROGRESS COMPLETED is posted on the bus. The thread then goes to sleep and the
  assynchronous operation completed.

  The RTSP protocol requires to send a TEARDOWN request to the server
  before closing the connection and destroying the socket. A state change to the
  READY state will issue the TEARDOWN request in the background and notify the
  application of this pending request with a PROGRESS message.

  The application might want to only go to the NULL state after it got confirmation
  that the TEARDOWN request completed or it might choose to go to NULL after a
  timeout. It might also be possible that the application just want to close the
  socket as fast as possible without waiting for completion of the TEARDOWN request.

 * Network performance measuring

  DNS lookup and connection times can be measured by calculating the elapsed
  time between the various PROGRESS messages.
  


Messages
~~~~~~~~

 A new PROGRESS message will be created.
 The following fields will be contained in the message:

  - "type", GST_TYPE_PROGRESS_TYPE

      - a set of types to define the type of progress

        GST_PROGRESS_TYPE_START: A new task is started in the background
        GST_PROGRESS_TYPE_CONTINUE: The previous tasks completed and a new
                  one continues. This is done so that the application can follow
                  a set of continuous tasks and react to COMPLETE only when the
                  element completely finished.
        GST_PROGRESS_TYPE_CANCELED: A task is canceled by the user.
        GST_PROGRESS_TYPE_ERROR: A task stopped because of an error. In case of
                  an error, an error message will have been posted before.
        GST_PROGRESS_TYPE_COMPLETE: A task completed successfully.

  - "code", G_TYPE_STRING

     A generic extensible string that can be used to programatically determine the
     action that is in progress. Some standard predefined codes will be
     defined.

  - "text", G_TYPE_STRING

     A user visible string detailing the action.

  - "percent", G_TYPE_INT  between 0 and 100

    Progress of the action as a percentage, the following values are allowed:
      - GST_PROGRESS_TYPE_START always has a 0% value.
      - GST_PROGRESS_TYPE_CONTINUE have a value between 0 and 100
      - GST_PROGRESS_TYPE_CANCELED, GST_PROGRESS_TYPE_ERROR and
        GST_PROGRESS_TYPE_COMPLETE always have a 100% value.

  - "timeout", G_TYPE_INT  in milliseconds

     The timeout of the async operation. -1 if unknown/unlimited..
     This field can be interesting to the application when it wants to display
     some sort of progress indication.

  - ....

     Depending on the code, more fields can be put here.

{'fraction_non_alphanumeric': 0.02851422259044463, 'fraction_numerical': 0.0020022093344380008, 'mean_word_length': 3.607188295165394, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4413778', 'n_tokens_mistral': 3477, 'n_tokens_neox': 3285, 'n_words': 2103}