go.temporal.io/server@v1.23.0/common/persistence/history_manager_util.go (about)

     1  // The MIT License
     2  //
     3  // Copyright (c) 2020 Temporal Technologies Inc.  All rights reserved.
     4  //
     5  // Copyright (c) 2020 Uber Technologies, Inc.
     6  //
     7  // Permission is hereby granted, free of charge, to any person obtaining a copy
     8  // of this software and associated documentation files (the "Software"), to deal
     9  // in the Software without restriction, including without limitation the rights
    10  // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
    11  // copies of the Software, and to permit persons to whom the Software is
    12  // furnished to do so, subject to the following conditions:
    13  //
    14  // The above copyright notice and this permission notice shall be included in
    15  // all copies or substantial portions of the Software.
    16  //
    17  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
    18  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
    19  // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
    20  // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
    21  // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
    22  // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
    23  // THE SOFTWARE.
    24  
    25  package persistence
    26  
    27  import (
    28  	"context"
    29  	"sort"
    30  
    31  	historypb "go.temporal.io/api/history/v1"
    32  
    33  	persistencespb "go.temporal.io/server/api/persistence/v1"
    34  )
    35  
    36  // ReadFullPageEvents reads a full page of history events from ExecutionManager. Due to storage format of V2 History
    37  // it is not guaranteed that pageSize amount of data is returned. Function returns the list of history events, the size
    38  // of data read, the next page token, and an error if present.
    39  func ReadFullPageEvents(
    40  	ctx context.Context,
    41  	executionMgr ExecutionManager,
    42  	req *ReadHistoryBranchRequest,
    43  ) ([]*historypb.HistoryEvent, int, []byte, error) {
    44  	var historyEvents []*historypb.HistoryEvent
    45  	size := 0
    46  	for {
    47  		response, err := executionMgr.ReadHistoryBranch(ctx, req)
    48  		if err != nil {
    49  			return nil, 0, nil, err
    50  		}
    51  		historyEvents = append(historyEvents, response.HistoryEvents...)
    52  		size += response.Size
    53  		if len(historyEvents) >= req.PageSize || len(response.NextPageToken) == 0 {
    54  			return historyEvents, size, response.NextPageToken, nil
    55  		}
    56  		req.NextPageToken = response.NextPageToken
    57  	}
    58  }
    59  
    60  // ReadFullPageEventsByBatch reads a full page of history events by batch from ExecutionManager. Due to storage format of V2 History
    61  // it is not guaranteed that pageSize amount of data is returned. Function returns the list of history batches, the size
    62  // of data read, the next page token, and an error if present.
    63  func ReadFullPageEventsByBatch(
    64  	ctx context.Context,
    65  	executionMgr ExecutionManager,
    66  	req *ReadHistoryBranchRequest,
    67  ) ([]*historypb.History, int, []byte, error) {
    68  	var historyBatches []*historypb.History
    69  	eventsRead := 0
    70  	size := 0
    71  	for {
    72  		response, err := executionMgr.ReadHistoryBranchByBatch(ctx, req)
    73  		if err != nil {
    74  			return nil, 0, nil, err
    75  		}
    76  		historyBatches = append(historyBatches, response.History...)
    77  		for _, batch := range response.History {
    78  			eventsRead += len(batch.Events)
    79  		}
    80  		size += response.Size
    81  		if eventsRead >= req.PageSize || len(response.NextPageToken) == 0 {
    82  			return historyBatches, size, response.NextPageToken, nil
    83  		}
    84  		req.NextPageToken = response.NextPageToken
    85  	}
    86  }
    87  
    88  // ReadFullPageEventsReverse reads a full page of history events from ExecutionManager in reverse orcer. Due to storage
    89  // format of V2 History it is not guaranteed that pageSize amount of data is returned. Function returns the list of
    90  // history events, the size of data read, the next page token, and an error if present.
    91  func ReadFullPageEventsReverse(
    92  	ctx context.Context,
    93  	executionMgr ExecutionManager,
    94  	req *ReadHistoryBranchReverseRequest,
    95  ) ([]*historypb.HistoryEvent, int, []byte, error) {
    96  	var historyEvents []*historypb.HistoryEvent
    97  	size := 0
    98  	for {
    99  		response, err := executionMgr.ReadHistoryBranchReverse(ctx, req)
   100  		if err != nil {
   101  			return nil, 0, nil, err
   102  		}
   103  		historyEvents = append(historyEvents, response.HistoryEvents...)
   104  		size += response.Size
   105  		if len(historyEvents) >= req.PageSize || len(response.NextPageToken) == 0 {
   106  			return historyEvents, size, response.NextPageToken, nil
   107  		}
   108  		req.NextPageToken = response.NextPageToken
   109  	}
   110  }
   111  
   112  // GetBeginNodeID gets node id from last ancestor
   113  func GetBeginNodeID(bi *persistencespb.HistoryBranch) int64 {
   114  	if len(bi.Ancestors) == 0 {
   115  		// root branch
   116  		return 1
   117  	}
   118  	idx := len(bi.Ancestors) - 1
   119  	return bi.Ancestors[idx].GetEndNodeId()
   120  }
   121  
   122  func sortAncestors(ans []*persistencespb.HistoryBranchRange) {
   123  	if len(ans) > 0 {
   124  		// sort ans based onf EndNodeID so that we can set BeginNodeID
   125  		sort.Slice(ans, func(i, j int) bool { return (ans)[i].GetEndNodeId() < (ans)[j].GetEndNodeId() })
   126  		(ans)[0].BeginNodeId = int64(1)
   127  		for i := 1; i < len(ans); i++ {
   128  			(ans)[i].BeginNodeId = (ans)[i-1].GetEndNodeId()
   129  		}
   130  	}
   131  }