You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2019/10/17 21:51:44 UTC

[tomcat] branch 7.0.x updated: Update state definitions and associated diagram (now a lot simpler)

This is an automated email from the ASF dual-hosted git repository.

markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git


The following commit(s) were added to refs/heads/7.0.x by this push:
     new 6e0e4d9  Update state definitions and associated diagram (now a lot simpler)
6e0e4d9 is described below

commit 6e0e4d992ba4bef6483517726cb87edfde9518e3
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Oct 17 22:51:27 2019 +0100

    Update state definitions and associated diagram (now a lot simpler)
---
 java/org/apache/coyote/AsyncStateMachine.java | 161 ++++++++++++--------------
 1 file changed, 75 insertions(+), 86 deletions(-)

diff --git a/java/org/apache/coyote/AsyncStateMachine.java b/java/org/apache/coyote/AsyncStateMachine.java
index 3200fbe..e407edf 100644
--- a/java/org/apache/coyote/AsyncStateMachine.java
+++ b/java/org/apache/coyote/AsyncStateMachine.java
@@ -30,101 +30,90 @@ import org.apache.tomcat.util.security.PrivilegedSetTccl;
  * <pre>
  * The internal states that are used are:
  * DISPATCHED       - Standard request. Not in Async mode.
- * STARTING         - ServletRequest.startAsync() has been called but the
- *                    request in which that call was made has not finished
- *                    processing.
- * STARTED          - ServletRequest.startAsync() has been called and the
- *                    request in which that call was made has finished
- *                    processing.
+ * STARTING         - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() but service() has not exited.
+ * STARTED          - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() and service() has exited.
  * MUST_COMPLETE    - ServletRequest.startAsync() followed by complete() have
  *                    been called during a single Servlet.service() method. The
- *                    complete() will be processed as soon as the request
- *                    finishes.
- * COMPLETE_PENDING - ServletRequest.startAsync() has been called and before the
- *                    request in which that call was had finished processing,
- *                    complete() was called for a non-container thread. The
- *                    complete() will be processed as soon as the request
- *                    finishes. This is different to MUST_COMPLETE because of
- *                    differences required to avoid race conditions during error
- *                    handling.
+ *                    complete() will be processed as soon as Servlet.service()
+ *                    exits.
+ * COMPLETE_PENDING - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() but, before service() exited, complete()
+ *                    was called from another thread. The complete() will
+ *                    be processed as soon as Servlet.service() exits.
  * COMPLETING       - The call to complete() was made once the request was in
- *                    the STARTED state. May or may not be triggered by a
- *                    container thread - depends if start(Runnable) was used.
+ *                    the STARTED state.
  * TIMING_OUT       - The async request has timed out and is waiting for a call
- *                    to complete(). If that isn't made, the error state will
- *                    entered.
+ *                    to complete() or dispatch(). If that isn't made, the error
+ *                    state will be entered.
  * MUST_DISPATCH    - ServletRequest.startAsync() followed by dispatch() have
  *                    been called during a single Servlet.service() method. The
- *                    dispatch() will be processed as soon as the request
- *                    finishes.
- * DISPATCH_PENDING - ServletRequest.startAsync() has been called and before the
- *                    request in which that call was had finished processing,
- *                    dispatch() was called for a non-container thread. The
- *                    dispatch() will be processed as soon as the request
- *                    finishes. This is different to MUST_DISPATCH because of
- *                    differences required to avoid race conditions during error
- *                    handling.
+ *                    dispatch() will be processed as soon as Servlet.service()
+ *                    exits.
+ * DISPATCH_PENDING - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() but, before service() exited, dispatch()
+ *                    was called from another thread. The dispatch() will
+ *                    be processed as soon as Servlet.service() exits.
  * DISPATCHING      - The dispatch is being processed.
- * MUST_ERROR       - ServletRequest.startAsync() has been called followed by an
- *                    I/O error on a non-container thread. The main purpose of
- *                    this state is to prevent additional async actions
- *                    (complete(), dispatch() etc.) on the non-container thread.
- *                    The container will perform the necessary error handling,
- *                    including ensuring that the AsyncLister.onError() method
- *                    is called.
+ * MUST_ERROR       - ServletRequest.startAsync() has been called from
+ *                    Servlet.service() but, before service() exited, an I/O
+ *                    error occured on another thread. The container will
+ *                    perform the necessary error handling when
+ *                    Servlet.service() exits.
  * ERROR            - Something went wrong.
  *
- * |-----------------»------|  |--«--------MUST_ERROR---------------«------------------------|
- * |                       \|/\|/                                                            |
- * |   |----------«-----E R R O R--«-----------------------«-------------------------------| |
- * |   |      complete() /|\/|\\ \--«---------------------------------«-----|              | ^
- * |   |                  |  |  \                                           |              | |
- * |   |    |-----»-------|  |   \-----------»----------|                   |              | |
- * |   |    |                |                          |dispatch()         |              | |
- * |   |    |                |                         \|/                  ^              | |
- * |   |    |                |          |--|timeout()   |                   |              | |
- * |   |    |     post()     |          | \|/           |     post()        |              | |
- * |   |    |    |---------- | --»DISPATCHED«---------- | --------------COMPLETING«-----|  | |
- * |   |    |    |           |   /|\/|\ |               |                | /|\ /|\      |  | |
- * |   |    |    |    |---»- | ---|  |  |startAsync()   |       timeout()|--|   |       |  | |
- * |   |    ^    ^    |      |       |  |               |                       |       |  ^ |
- * |   |    |    |    |   |-- \ -----|  |   complete()  |                       |post() |  | |
- * |   |    |    |    |   |    \        |     /--»----- | ---COMPLETE_PENDING-»-|       |  | |
- * |   |    |    |    |   |     \       |    /          |                               |  | |
- * |   |    |    |    |   ^      \      |   /           |                               |  | |
- * |  \|/   |    |    |   |       \    \|/ /   post()   |                               |  | |
- * | MUST_COMPLETE-«- | - | --«----STARTING--»--------- | -------------|                ^  | |
- * |         /|\      |   |  complete()  | \            |              |     complete() |  | |
- * |          |       |   |              |  \           |    post()    |     /----------|  | |
- * |          |       ^   |    dispatch()|   \          |    |-----|   |    /              | |
- * |          |       |   |              |    \         |    |     |   |   /               | |
- * |          |       |   |             \|/    \        |    |    \|/ \|/ /                | ^
- * |          |       |   |--«--MUST_DISPATCH-----«-----|    |--«--STARTED---»-------------| |
- * |          |       | dispatched() /|\   |     \                / |     \                  |
- * |          |       |               |    |      \              /  |      \  nct-io-error   |
- * |          |       |               |    |       \            /   |       \----»-----------|
- * |          |       |               |    |post()  \           |   |
- * ^          ^       |               |    |       \|/          |   |
- * |          |       ^               |    |  DISPATCH_PENDING  |   |
- * |          |       |               |    |  |post()           |   |
- * |          |       |               |    |  |      |----------|   |
- * |          |       |               |    |  |      |  dispatch()  |
- * |          |       |               |    |  |      |              |
- * |          |       |post()         |    |  |      |     timeout()|
- * |          |       |dispatched()   |   \|/\|/    \|/             |
- * |          |       |---«---------- | ---DISPATCHING              |
- * |          |                       |     |   /|\                 |
- * |          |                       |     |----|                  |
- * |          |                       |    timeout()                |
- * |          |                       |                             |
- * |          |                       |       dispatch()           \|/
- * |          |                       |-----------«-----------TIMING_OUT
- * |          |                                                 |   |
- * |          |-------«----------------------------------«------|   |
- * |                              complete()                        |
- * |                                                                |
- * |«--------«-------------------«-------------------------------«--|
- *                                 error()
+ *
+ * The valid state transitions are:
+ *
+ *                  post()                                        dispatched()
+ *    |-------»------------------»---------|    |-------«-----------------------«-----|
+ *    |                                    |    |                                     |
+ *    |                                    |    |        post()                       |
+ *    |               post()              \|/  \|/       dispatched()                 |
+ *    |           |-----»----------------»DISPATCHED«-------------«-------------|     |
+ *    |           |                          | /|\ |                            |     |
+ *    |           |              startAsync()|  |--|timeout()                   |     |
+ *    ^           |                          |                                  |     |
+ *    |           |        complete()        |                  dispatch()      ^     |
+ *    |           |   |--«---------------«-- | ---«--MUST_ERROR--»-----|        |     |
+ *    |           |   |                      |         /|\             |        |     |
+ *    |           ^   |                      |          |              |        |     |
+ *    |           |   |                      |    /-----|error()       |        |     |
+ *    |           |   |                      |   /                     |        ^     |
+ *    |           |  \|/  ST-complete()     \|/ /   ST-dispatch()     \|/       |     |
+ *    |    MUST_COMPLETE«--------«--------STARTING--------»---------»MUST_DISPATCH    |
+ *    |                                    / | \                                      |
+ *    |                                   /  |  \                                     |
+ *    |                    OT-complete() /   |   \    OT-dispatch()                   |
+ *    |   COMPLETE_PENDING«------«------/    |    \-------»---------»DISPATCH_PENDING |
+ *    |          |                           |                           |            |
+ *    |    post()|   timeout()         post()|   post()            post()|  timeout() |
+ *    |          |   |--|                    |  |--|                     |    |--|    |
+ *    |         \|/ \|/ |   complete()      \|/\|/ |   dispatch()       \|/  \|/ |    |
+ *    |--«-----COMPLETING«--------«----------STARTED--------»---------»DISPATCHING----|
+ *            /|\  /|\                       |                             /|\ /|\
+ *             |    |                        |                              |   |
+ *             |    |               timeout()|                              |   |
+ *             |    |                        |                              |   |
+ *             |    |                        |                              |   |
+ *             |    |                        |                              |   |
+ *             |    |                        |                              |   |
+ *             |    |                        |                              |   |
+ *             |    |                        |                              |   |
+ *             |    |                        |                              |   |
+ *             |    |                        |                              |   |
+ *             |    |       complete()      \|/         dispatch()          |   |
+ *             |    |------------«-------TIMING_OUT--------»----------------|   |
+ *             |                                                                |
+ *             |            complete()                     dispatch()           |
+ *             |---------------«-----------ERROR--------------»-----------------|
+ *
+ *
+ * Notes: * For clarity, the transitions to ERROR which are valid from every state apart from
+ *          STARTING are not shown.
+ *        * All transitions may happen on either the Servlet.service() thread (ST) or on any
+ *          other thread (OT) unless explicitly marked.
  * </pre>
  */
 public class AsyncStateMachine<S> {


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org