activities.go ×15

Frontier kind: Joint frontier

unlabeled · c_af1d9fb1fe9e

1 test · 3009 LOC · 140 files · introduces 1 test · 93 LOC · 2 files

Introduces — evidence that enters the hierarchy at this concept

Code
17 ranges93 lines · 2 files
Tests
1 test

Contains — complete concept membership

All code (extent)
542 ranges3009 lines · 140 files · Browse complete extent
All tests (intent)
1 testBrowse complete intent

Neighbourhood graph

The orange circle is the focus. Violet and green circles are every ancestor and descendant, broader and narrower, at any distance; blue squares and pink diamonds are the introduced files and exact introduced tests of every visible concept, not only the focus's. Arrows point from broader to narrower concepts and bridge only concepts omitted from this view. Undirected links show source or test introduction. Concept and file size follows LOC; exact test nodes use test-count units.

Introduced files, introduced tests, and structurally relevant concept specialization

In the embedded map, ordinary wheel input scrolls the page; use the visible controls to zoom and drag to pan. Open the full-screen map for canvas navigation: wheel pans, Ctrl/Command plus wheel zooms, and arrow keys pan when this region is focused. On touch screens, open the full-screen map to pan or pinch. If JavaScript or WebGL is unavailable, use the native relationship evidence on this page.

Graph controls are ready.

Interactive rendering requires JavaScript and WebGL. Use the native relationship evidence on this page while the interactive map is unavailable.

Native relationship evidence

Every exact file and test below is linked only from the concept that introduces it.

Introduced tests

Every collected test enters the hierarchy at exactly one concept.

1 test introduced at this concept.

Introduced code

Every collected source range enters the hierarchy at exactly one concept.

2 files ranked by introduced lines: 93 introduced LOC across 17 ranges. Expand a file to inspect source; the > gutter marks introduced lines.

go.temporal.io/server/service/worker/migration/activities.go 85 introduced LOC · 15 ranges

Open complete file

1088 // WaitCatchup waits for the CatchupCluster to catch necessary data from the current cluster,
1089 // ensuring it has caught up to the TargetCluster's ack level for the specified namespace.
1090 > func (a *activities) WaitCatchup(ctx context.Context, params CatchUpParams) error { activities.go
1091 > ctx = headers.SetCallerInfo(ctx, headers.NewCallerInfo(params.Namespace, headers.CallerTypeAPI, ""))
1092 >
1093 > descResp, err := a.frontendClient.DescribeNamespace(ctx, &workflowservice.DescribeNamespaceRequest{
1094 > Namespace: params.Namespace,
1095 > })
1096 > if err != nil {
1097 return err
1098 }
1099
1100 > targetCluster := params.TargetCluster activities.go
1101 > if targetCluster == "" {
1102 > targetCluster = descResp.ReplicationConfig.GetActiveClusterName()
1103 > }
1104
1105 > waitCatchupRequest := waitCatchupRequest{ activities.go
1106 > Namespace: params.Namespace,
1107 > CatchupCluster: params.CatchupCluster,
1108 > TargetCluster: targetCluster,
1109 > }
1110 >
1111 > targetAckIDOnShard, err := a.getTargetClusterReplicationStatus(ctx, waitCatchupRequest)
1112 > if err != nil {
1113 return err
1114 }
1115
1116 > for { activities.go
1117 > done, err := a.checkReplicationOnRemoteCluster(ctx, waitCatchupRequest, targetAckIDOnShard)
1118 > if err != nil {
1119 return err
1120 }
1121 > if done { activities.go
1122 > return nil
1123 > }
1124
1125 // keep waiting and check again
1130
1131 // Check if remote cluster has caught up on all shards on replication tasks from target replica.
1132 > func (a *activities) getTargetClusterReplicationStatus(ctx context.Context, waitRequest waitCatchupRequest) (map[int32]int64, error) { activities.go
1133 > targetAckIDOnShard := make(map[int32]int64)
1134 >
1135 > resp, err := a.HistoryClient.GetReplicationStatus(ctx, &historyservice.GetReplicationStatusRequest{
1136 > RemoteClusters: []string{waitRequest.TargetCluster}, // only the specified remote cluster
1137 > })
1138 > if err != nil {
1139 return targetAckIDOnShard, err
1140 }
1141
1142 // record the acked task id from active for each shard
1143 > for _, shard := range resp.Shards { activities.go
1144 > activeInfo, hasActiveInfo := shard.RemoteClusters[waitRequest.TargetCluster]
1145 > if hasActiveInfo {
1146 > targetAckIDOnShard[shard.ShardId] = activeInfo.AckedTaskId
1147 > }
1148 }
1149
1150 > return targetAckIDOnShard, nil activities.go
1151 }
1152
1153 // Check if remote cluster has caught up on all shards on replication tasks from target replica.
1154 > func (a *activities) checkReplicationOnRemoteCluster(ctx context.Context, waitRequest waitCatchupRequest, requiredMinTaskIDPerShard map[int32]int64) (bool, error) { activities.go
1155 > resp, err := a.HistoryClient.GetReplicationStatus(ctx, &historyservice.GetReplicationStatusRequest{
1156 > RemoteClusters: []string{waitRequest.CatchupCluster}, // only the specified remote cluster
1157 > })
1158 > if err != nil {
1159 return false, err
1160 }
1161
1162 > localShards := resp.Shards activities.go
1163 >
1164 > shardStatuses := make([]shardStatus, 0, len(localShards))
1165 >
1166 > // check that on every shard, all source clusters have caught up with target cluster
1167 > for _, localShard := range localShards {
1168 > remoteShardProgress, hasRemoteShardProgress := localShard.RemoteClusters[waitRequest.CatchupCluster]
1169 > if !hasRemoteShardProgress {
1170 a.Logger.Info("GetReplicationStatus response missing expected remote cluster for shard during remote cluster replication catchup",
1171 tag.ShardID(localShard.ShardId),
1178 }
1179
1180 > laggingTasks := localShard.MaxReplicationTaskId - remoteShardProgress.AckedTaskId activities.go
1181 >
1182 > requiredMinTaskID, exists := requiredMinTaskIDPerShard[localShard.ShardId]
1183 >
1184 > // If the target acked task ID is NOT found, the shard is considered ready, as the remote ack level
1185 > // is assumed to be more up-to-date than the active ack level.
1186 > noTargetAckID := !exists
1187 > fullyCaughtUp := laggingTasks <= 0
1188 > reachedTarget := remoteShardProgress.AckedTaskId >= requiredMinTaskID
1189 >
1190 > status := shardStatus{
1191 > shardID: localShard.GetShardId(),
1192 > laggingTasks: laggingTasks,
1193 > isReady: noTargetAckID || fullyCaughtUp || reachedTarget,
1194 > }
1195 >
1196 > shardStatuses = append(shardStatuses, status)
1197 }
1198
1199 > var ( activities.go
1200 > readyShardCount int
1201 > notReadyShardCount int
1202 >
1203 > maxLaggingTasksShardID int32
1204 > maxLaggingTasks int64
1205 > )
1206 >
1207 > for _, status := range shardStatuses {
1208 > if status.isReady {
1209 > readyShardCount++
1210 > } else {
1211 notReadyShardCount++
1212 }
1213
1214 > if status.laggingTasks > maxLaggingTasks { activities.go
1215 maxLaggingTasks = status.laggingTasks
1216 maxLaggingTasksShardID = status.shardID
1218 }
1219
1220 > isReady := notReadyShardCount == 0 activities.go
1221 >
1222 > if !isReady {
1223 a.Logger.Info("Wait catchup not ready",
1224 tag.String("Namespace", waitRequest.Namespace),
1234 }
1235
1236 > return isReady, nil activities.go
1237 }
1238
go.temporal.io/server/api/historyservice/v1/request_response.pb.go 8 introduced LOC · 2 ranges

Open complete file

6663 }
6664
6665 > func (x *GetReplicationStatusRequest) String() string { request_response.pb.go
6666 > return protoimpl.X.MessageStringOf(x)
6667 > }
6668
6669 func (*GetReplicationStatusRequest) ProtoMessage() {}
6672 mi := &file_temporal_server_api_historyservice_v1_request_response_proto_msgTypes[94]
6673 if x != nil {
6674 > ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) request_response.pb.go
6675 > if ms.LoadMessageInfo() == nil {
6676 > ms.StoreMessageInfo(mi)
6677 > }
6678 > return ms
6679 }
6680 return mi.MessageOf(x)