github.com/cockroachdb/cockroach@v20.2.0-alpha.1+incompatible/pkg/ui/src/redux/queryManager/reducer.ts (about)

     1  // Copyright 2018 The Cockroach Authors.
     2  //
     3  // Use of this software is governed by the Business Source License
     4  // included in the file licenses/BSL.txt.
     5  //
     6  // As of the Change Date specified in that file, in accordance with
     7  // the Business Source License, use of this software will be governed
     8  // by the Apache License, Version 2.0, included in the file
     9  // licenses/APL.txt.
    10  
    11  import moment from "moment";
    12  import { Action } from "redux";
    13  
    14  import nextState from "src/util/nextState";
    15  
    16  const QUERY_BEGIN = "cockroachui/queries/QUERY_BEGIN";
    17  const QUERY_ERROR = "cockroachui/queries/QUERY_ERROR";
    18  const QUERY_COMPLETE = "cockroachui/queries/QUERY_COMPLETE";
    19  
    20  interface QueryBeginAction extends Action {
    21      type: typeof QUERY_BEGIN;
    22      payload: {
    23          id: string;
    24      };
    25  }
    26  
    27  interface QueryErrorAction extends Action {
    28      type: typeof QUERY_ERROR;
    29      payload: {
    30          id: string;
    31          error: Error;
    32          timestamp: moment.Moment;
    33      };
    34  }
    35  
    36  interface QueryCompleteAction extends Action {
    37      type: typeof QUERY_COMPLETE;
    38      payload: {
    39          id: string;
    40          timestamp: moment.Moment;
    41      };
    42  }
    43  
    44  type QueryAction = QueryBeginAction | QueryErrorAction | QueryCompleteAction;
    45  
    46  /**
    47   * queryBegin is dispatched by the query manager whenever the query with the
    48   * given ID has started execution.
    49   */
    50  export function queryBegin(id: string): QueryBeginAction {
    51      return {
    52          type: QUERY_BEGIN,
    53          payload: {
    54              id,
    55          },
    56      };
    57  }
    58  
    59  /**
    60   * queryError is dispatched by the query manager whenever the query with the
    61   * given ID has stopped due to an error condition. This action contains the
    62   * returned error, along with the timestamp when the error was received.
    63   */
    64  export function queryError(id: string, error: Error, timestamp: moment.Moment): QueryErrorAction {
    65      return {
    66          type: QUERY_ERROR,
    67          payload: {
    68              id,
    69              error,
    70              timestamp,
    71          },
    72      };
    73  }
    74  
    75  /**
    76   * queryComplete is dispatched by the query manager whenever the query with the
    77   * given ID has completed successfully. It includes the timestamp when the query
    78   * was completed.
    79   */
    80  export function queryComplete(id: string, timestamp: moment.Moment): QueryCompleteAction {
    81      return {
    82          type: QUERY_COMPLETE,
    83          payload: {
    84              id,
    85              timestamp,
    86          },
    87      };
    88  }
    89  
    90  /**
    91   * ManagedQueryState maintains the current state for a single managed query.
    92   */
    93  export class ManagedQueryState {
    94      // True if this query is currently running asynchronously.
    95      isRunning = false;
    96      // If the previous attempt to run this query ended with an error, this field
    97      // contains that error.
    98      lastError: Error = null;
    99      // Contains the timestamp when the query last compeleted, regardless of
   100      // whether it succeeded or encountered an error.
   101      completedAt: moment.Moment = null;
   102  }
   103  
   104  /**
   105   * managedQueryReducer reduces actions for a single managed query.
   106   */
   107  export function managedQueryReducer(
   108      state = new ManagedQueryState(), action: QueryAction,
   109  ): ManagedQueryState {
   110      switch (action.type) {
   111          case QUERY_BEGIN:
   112              return nextState(state, {
   113                  isRunning: true,
   114                  lastError: null,
   115                  completedAt: null,
   116              });
   117          case QUERY_ERROR:
   118              return nextState(state, {
   119                  isRunning: false,
   120                  lastError: action.payload.error,
   121                  completedAt: action.payload.timestamp,
   122              });
   123          case QUERY_COMPLETE:
   124              return nextState(state, {
   125                  isRunning: false,
   126                  lastError: null,
   127                  completedAt: action.payload.timestamp,
   128              });
   129          default:
   130              return state;
   131      }
   132  }
   133  
   134  /**
   135   * QueryManagerState maintains the state for all queries being managed.
   136   */
   137  export interface QueryManagerState {
   138      [id: string]: ManagedQueryState;
   139  }
   140  
   141  /**
   142   * queryManagerReducer reduces actions for a query collection, multiplexing
   143   * incoming actions to individual query reducers by ID.
   144   */
   145  export function queryManagerReducer(
   146      state: QueryManagerState = {}, action: QueryAction,
   147  ): QueryManagerState {
   148      switch (action.type) {
   149          case QUERY_BEGIN:
   150          case QUERY_ERROR:
   151          case QUERY_COMPLETE:
   152              return {
   153                  ...state,
   154                  [action.payload.id]: managedQueryReducer(state[action.payload.id], action),
   155              };
   156          default:
   157              return state;
   158      }
   159  }