go.temporal.io/server@v1.23.0/common/persistence/cassandra/mutable_state_task_store.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 cassandra 26 27 import ( 28 "context" 29 "fmt" 30 "time" 31 32 "go.temporal.io/api/serviceerror" 33 34 "go.temporal.io/server/common/log" 35 p "go.temporal.io/server/common/persistence" 36 "go.temporal.io/server/common/persistence/nosql/nosqlplugin/cassandra/gocql" 37 "go.temporal.io/server/common/persistence/serialization" 38 "go.temporal.io/server/service/history/tasks" 39 ) 40 41 const ( 42 templateCreateTransferTaskQuery = `INSERT INTO executions (` + 43 `shard_id, type, namespace_id, workflow_id, run_id, transfer, transfer_encoding, visibility_ts, task_id) ` + 44 `VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)` 45 46 templateCreateReplicationTaskQuery = `INSERT INTO executions (` + 47 `shard_id, type, namespace_id, workflow_id, run_id, replication, replication_encoding, visibility_ts, task_id) ` + 48 `VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)` 49 50 templateCreateVisibilityTaskQuery = `INSERT INTO executions (` + 51 `shard_id, type, namespace_id, workflow_id, run_id, visibility_task_data, visibility_task_encoding, visibility_ts, task_id) ` + 52 `VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)` 53 54 templateCreateTimerTaskQuery = `INSERT INTO executions (` + 55 `shard_id, type, namespace_id, workflow_id, run_id, timer, timer_encoding, visibility_ts, task_id) ` + 56 `VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)` 57 58 templateCreateHistoryTaskQuery = `INSERT INTO executions (` + 59 `shard_id, type, namespace_id, workflow_id, run_id, task_data, task_encoding, visibility_ts, task_id) ` + 60 `VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)` 61 62 templateGetHistoryImmediateTasksQuery = `SELECT task_id, task_data, task_encoding ` + 63 `FROM executions ` + 64 `WHERE shard_id = ? ` + 65 `and type = ? ` + 66 `and namespace_id = ? ` + 67 `and workflow_id = ? ` + 68 `and run_id = ? ` + 69 `and visibility_ts = ? ` + 70 `and task_id >= ? ` + 71 `and task_id < ?` 72 73 templateGetHistoryScheduledTasksQuery = `SELECT visibility_ts, task_id, task_data, task_encoding ` + 74 `FROM executions ` + 75 `WHERE shard_id = ? ` + 76 `and type = ?` + 77 `and namespace_id = ? ` + 78 `and workflow_id = ?` + 79 `and run_id = ?` + 80 `and visibility_ts >= ? ` + 81 `and visibility_ts < ?` 82 83 templateGetTransferTasksQuery = `SELECT task_id, transfer, transfer_encoding ` + 84 `FROM executions ` + 85 `WHERE shard_id = ? ` + 86 `and type = ? ` + 87 `and namespace_id = ? ` + 88 `and workflow_id = ? ` + 89 `and run_id = ? ` + 90 `and visibility_ts = ? ` + 91 `and task_id >= ? ` + 92 `and task_id < ?` 93 94 templateGetVisibilityTasksQuery = `SELECT task_id, visibility_task_data, visibility_task_encoding ` + 95 `FROM executions ` + 96 `WHERE shard_id = ? ` + 97 `and type = ? ` + 98 `and namespace_id = ? ` + 99 `and workflow_id = ? ` + 100 `and run_id = ? ` + 101 `and visibility_ts = ? ` + 102 `and task_id >= ? ` + 103 `and task_id < ?` 104 105 templateGetReplicationTasksQuery = `SELECT task_id, replication, replication_encoding ` + 106 `FROM executions ` + 107 `WHERE shard_id = ? ` + 108 `and type = ? ` + 109 `and namespace_id = ? ` + 110 `and workflow_id = ? ` + 111 `and run_id = ? ` + 112 `and visibility_ts = ? ` + 113 `and task_id >= ? ` + 114 `and task_id < ?` 115 116 templateIsQueueEmptyQuery = `SELECT task_id ` + 117 `FROM executions ` + 118 `WHERE shard_id = ? ` + 119 `and type = ? ` + 120 `and namespace_id = ? ` + 121 `and workflow_id = ? ` + 122 `and run_id = ? ` + 123 `and visibility_ts = ? ` + 124 `and task_id >= ? ` + 125 `limit 1` 126 127 templateCompleteTransferTaskQuery = `DELETE FROM executions ` + 128 `WHERE shard_id = ? ` + 129 `and type = ? ` + 130 `and namespace_id = ? ` + 131 `and workflow_id = ? ` + 132 `and run_id = ? ` + 133 `and visibility_ts = ? ` + 134 `and task_id = ?` 135 136 templateRangeCompleteTransferTaskQuery = `DELETE FROM executions ` + 137 `WHERE shard_id = ? ` + 138 `and type = ? ` + 139 `and namespace_id = ? ` + 140 `and workflow_id = ? ` + 141 `and run_id = ? ` + 142 `and visibility_ts = ? ` + 143 `and task_id >= ? ` + 144 `and task_id < ?` 145 146 templateCompleteVisibilityTaskQuery = templateCompleteTransferTaskQuery 147 148 templateRangeCompleteVisibilityTaskQuery = templateRangeCompleteTransferTaskQuery 149 150 templateCompleteReplicationTaskQuery = templateCompleteTransferTaskQuery 151 152 templateRangeCompleteReplicationTaskQuery = templateRangeCompleteTransferTaskQuery 153 154 templateCompleteHistoryTaskQuery = templateCompleteTransferTaskQuery 155 156 templateRangeCompleteHistoryImmediateTasksQuery = templateRangeCompleteTransferTaskQuery 157 158 templateRangeCompleteHistoryScheduledTasksQuery = templateRangeCompleteTimerTaskQuery 159 160 templateGetTimerTasksQuery = `SELECT visibility_ts, task_id, timer, timer_encoding ` + 161 `FROM executions ` + 162 `WHERE shard_id = ? ` + 163 `and type = ?` + 164 `and namespace_id = ? ` + 165 `and workflow_id = ?` + 166 `and run_id = ?` + 167 `and visibility_ts >= ? ` + 168 `and visibility_ts < ?` 169 170 templateCompleteTimerTaskQuery = `DELETE FROM executions ` + 171 `WHERE shard_id = ? ` + 172 `and type = ? ` + 173 `and namespace_id = ? ` + 174 `and workflow_id = ?` + 175 `and run_id = ?` + 176 `and visibility_ts = ? ` + 177 `and task_id = ?` 178 179 templateRangeCompleteTimerTaskQuery = `DELETE FROM executions ` + 180 `WHERE shard_id = ? ` + 181 `and type = ? ` + 182 `and namespace_id = ? ` + 183 `and workflow_id = ?` + 184 `and run_id = ?` + 185 `and visibility_ts >= ? ` + 186 `and visibility_ts < ?` 187 ) 188 189 type ( 190 MutableStateTaskStore struct { 191 Session gocql.Session 192 Logger log.Logger 193 } 194 ) 195 196 func NewMutableStateTaskStore( 197 session gocql.Session, 198 logger log.Logger, 199 ) *MutableStateTaskStore { 200 return &MutableStateTaskStore{ 201 Session: session, 202 Logger: logger, 203 } 204 } 205 206 func (d *MutableStateTaskStore) RegisterHistoryTaskReader( 207 _ context.Context, 208 _ *p.RegisterHistoryTaskReaderRequest, 209 ) error { 210 // no-op 211 return nil 212 } 213 214 func (d *MutableStateTaskStore) UnregisterHistoryTaskReader( 215 _ context.Context, 216 _ *p.UnregisterHistoryTaskReaderRequest, 217 ) { 218 // no-op 219 } 220 221 func (d *MutableStateTaskStore) UpdateHistoryTaskReaderProgress( 222 _ context.Context, 223 _ *p.UpdateHistoryTaskReaderProgressRequest, 224 ) { 225 // no-op 226 } 227 228 func (d *MutableStateTaskStore) AddHistoryTasks( 229 ctx context.Context, 230 request *p.InternalAddHistoryTasksRequest, 231 ) error { 232 batch := d.Session.NewBatch(gocql.LoggedBatch).WithContext(ctx) 233 234 if err := applyTasks( 235 batch, 236 request.ShardID, 237 request.Tasks, 238 ); err != nil { 239 return err 240 } 241 242 batch.Query(templateUpdateLeaseQuery, 243 request.RangeID, 244 request.ShardID, 245 rowTypeShard, 246 rowTypeShardNamespaceID, 247 rowTypeShardWorkflowID, 248 rowTypeShardRunID, 249 defaultVisibilityTimestamp, 250 rowTypeShardTaskID, 251 request.RangeID, 252 ) 253 254 previous := make(map[string]interface{}) 255 applied, iter, err := d.Session.MapExecuteBatchCAS(batch, previous) 256 if err != nil { 257 return gocql.ConvertError("AddTasks", err) 258 } 259 defer func() { 260 _ = iter.Close() 261 }() 262 263 if !applied { 264 if previousRangeID, ok := previous["range_id"].(int64); ok && previousRangeID != request.RangeID { 265 // CreateWorkflowExecution failed because rangeID was modified 266 return &p.ShardOwnershipLostError{ 267 ShardID: request.ShardID, 268 Msg: fmt.Sprintf("Failed to add tasks. Request RangeID: %v, Actual RangeID: %v", request.RangeID, previousRangeID), 269 } 270 } else { 271 return serviceerror.NewUnavailable("AddTasks operation failed: %v") 272 } 273 } 274 return nil 275 } 276 277 func (d *MutableStateTaskStore) GetHistoryTasks( 278 ctx context.Context, 279 request *p.GetHistoryTasksRequest, 280 ) (*p.InternalGetHistoryTasksResponse, error) { 281 switch request.TaskCategory.ID() { 282 case tasks.CategoryIDTransfer: 283 return d.getTransferTasks(ctx, request) 284 case tasks.CategoryIDTimer: 285 return d.getTimerTasks(ctx, request) 286 case tasks.CategoryIDVisibility: 287 return d.getVisibilityTasks(ctx, request) 288 case tasks.CategoryIDReplication: 289 return d.getReplicationTasks(ctx, request) 290 default: 291 return d.getHistoryTasks(ctx, request) 292 } 293 } 294 295 func (d *MutableStateTaskStore) CompleteHistoryTask( 296 ctx context.Context, 297 request *p.CompleteHistoryTaskRequest, 298 ) error { 299 switch request.TaskCategory.ID() { 300 case tasks.CategoryIDTransfer: 301 return d.completeTransferTask(ctx, request) 302 case tasks.CategoryIDTimer: 303 return d.completeTimerTask(ctx, request) 304 case tasks.CategoryIDVisibility: 305 return d.completeVisibilityTask(ctx, request) 306 case tasks.CategoryIDReplication: 307 return d.completeReplicationTask(ctx, request) 308 default: 309 return d.completeHistoryTask(ctx, request) 310 } 311 } 312 313 func (d *MutableStateTaskStore) RangeCompleteHistoryTasks( 314 ctx context.Context, 315 request *p.RangeCompleteHistoryTasksRequest, 316 ) error { 317 switch request.TaskCategory.ID() { 318 case tasks.CategoryIDTransfer: 319 return d.rangeCompleteTransferTasks(ctx, request) 320 case tasks.CategoryIDTimer: 321 return d.rangeCompleteTimerTasks(ctx, request) 322 case tasks.CategoryIDVisibility: 323 return d.rangeCompleteVisibilityTasks(ctx, request) 324 case tasks.CategoryIDReplication: 325 return d.rangeCompleteReplicationTasks(ctx, request) 326 default: 327 return d.rangeCompleteHistoryTasks(ctx, request) 328 } 329 } 330 331 func (d *MutableStateTaskStore) getTransferTasks( 332 ctx context.Context, 333 request *p.GetHistoryTasksRequest, 334 ) (*p.InternalGetHistoryTasksResponse, error) { 335 336 // Reading transfer tasks need to be quorum level consistent, otherwise we could lose task 337 query := d.Session.Query(templateGetTransferTasksQuery, 338 request.ShardID, 339 rowTypeTransferTask, 340 rowTypeTransferNamespaceID, 341 rowTypeTransferWorkflowID, 342 rowTypeTransferRunID, 343 defaultVisibilityTimestamp, 344 request.InclusiveMinTaskKey.TaskID, 345 request.ExclusiveMaxTaskKey.TaskID, 346 ).WithContext(ctx) 347 iter := query.PageSize(request.BatchSize).PageState(request.NextPageToken).Iter() 348 349 response := &p.InternalGetHistoryTasksResponse{} 350 var taskID int64 351 var data []byte 352 var encoding string 353 354 for iter.Scan(&taskID, &data, &encoding) { 355 response.Tasks = append(response.Tasks, p.InternalHistoryTask{ 356 Key: tasks.NewImmediateKey(taskID), 357 Blob: p.NewDataBlob(data, encoding), 358 }) 359 360 taskID = 0 361 data = nil 362 encoding = "" 363 } 364 if len(iter.PageState()) > 0 { 365 response.NextPageToken = iter.PageState() 366 } 367 368 if err := iter.Close(); err != nil { 369 return nil, gocql.ConvertError("GetTransferTasks", err) 370 } 371 372 return response, nil 373 } 374 375 func (d *MutableStateTaskStore) completeTransferTask( 376 ctx context.Context, 377 request *p.CompleteHistoryTaskRequest, 378 ) error { 379 query := d.Session.Query(templateCompleteTransferTaskQuery, 380 request.ShardID, 381 rowTypeTransferTask, 382 rowTypeTransferNamespaceID, 383 rowTypeTransferWorkflowID, 384 rowTypeTransferRunID, 385 defaultVisibilityTimestamp, 386 request.TaskKey.TaskID, 387 ).WithContext(ctx) 388 389 err := query.Exec() 390 return gocql.ConvertError("CompleteTransferTask", err) 391 } 392 393 func (d *MutableStateTaskStore) rangeCompleteTransferTasks( 394 ctx context.Context, 395 request *p.RangeCompleteHistoryTasksRequest, 396 ) error { 397 query := d.Session.Query(templateRangeCompleteTransferTaskQuery, 398 request.ShardID, 399 rowTypeTransferTask, 400 rowTypeTransferNamespaceID, 401 rowTypeTransferWorkflowID, 402 rowTypeTransferRunID, 403 defaultVisibilityTimestamp, 404 request.InclusiveMinTaskKey.TaskID, 405 request.ExclusiveMaxTaskKey.TaskID, 406 ).WithContext(ctx) 407 408 err := query.Exec() 409 return gocql.ConvertError("RangeCompleteTransferTask", err) 410 } 411 412 func (d *MutableStateTaskStore) getTimerTasks( 413 ctx context.Context, 414 request *p.GetHistoryTasksRequest, 415 ) (*p.InternalGetHistoryTasksResponse, error) { 416 // Reading timer tasks need to be quorum level consistent, otherwise we could lose tasks 417 minTimestamp := p.UnixMilliseconds(request.InclusiveMinTaskKey.FireTime) 418 maxTimestamp := p.UnixMilliseconds(request.ExclusiveMaxTaskKey.FireTime) 419 query := d.Session.Query(templateGetTimerTasksQuery, 420 request.ShardID, 421 rowTypeTimerTask, 422 rowTypeTimerNamespaceID, 423 rowTypeTimerWorkflowID, 424 rowTypeTimerRunID, 425 minTimestamp, 426 maxTimestamp, 427 ).WithContext(ctx) 428 iter := query.PageSize(request.BatchSize).PageState(request.NextPageToken).Iter() 429 430 response := &p.InternalGetHistoryTasksResponse{} 431 var timestamp time.Time 432 var taskID int64 433 var data []byte 434 var encoding string 435 436 for iter.Scan(×tamp, &taskID, &data, &encoding) { 437 response.Tasks = append(response.Tasks, p.InternalHistoryTask{ 438 Key: tasks.NewKey(timestamp, taskID), 439 Blob: p.NewDataBlob(data, encoding), 440 }) 441 442 timestamp = time.Time{} 443 taskID = 0 444 data = nil 445 encoding = "" 446 } 447 if len(iter.PageState()) > 0 { 448 response.NextPageToken = iter.PageState() 449 } 450 451 if err := iter.Close(); err != nil { 452 return nil, gocql.ConvertError("GetTimerTasks", err) 453 } 454 455 return response, nil 456 } 457 458 func (d *MutableStateTaskStore) completeTimerTask( 459 ctx context.Context, 460 request *p.CompleteHistoryTaskRequest, 461 ) error { 462 ts := p.UnixMilliseconds(request.TaskKey.FireTime) 463 query := d.Session.Query(templateCompleteTimerTaskQuery, 464 request.ShardID, 465 rowTypeTimerTask, 466 rowTypeTimerNamespaceID, 467 rowTypeTimerWorkflowID, 468 rowTypeTimerRunID, 469 ts, 470 request.TaskKey.TaskID, 471 ).WithContext(ctx) 472 473 err := query.Exec() 474 return gocql.ConvertError("CompleteTimerTask", err) 475 } 476 477 func (d *MutableStateTaskStore) rangeCompleteTimerTasks( 478 ctx context.Context, 479 request *p.RangeCompleteHistoryTasksRequest, 480 ) error { 481 start := p.UnixMilliseconds(request.InclusiveMinTaskKey.FireTime) 482 end := p.UnixMilliseconds(request.ExclusiveMaxTaskKey.FireTime) 483 query := d.Session.Query(templateRangeCompleteTimerTaskQuery, 484 request.ShardID, 485 rowTypeTimerTask, 486 rowTypeTimerNamespaceID, 487 rowTypeTimerWorkflowID, 488 rowTypeTimerRunID, 489 start, 490 end, 491 ).WithContext(ctx) 492 493 err := query.Exec() 494 return gocql.ConvertError("RangeCompleteTimerTask", err) 495 } 496 497 func (d *MutableStateTaskStore) getReplicationTasks( 498 ctx context.Context, 499 request *p.GetHistoryTasksRequest, 500 ) (*p.InternalGetHistoryTasksResponse, error) { 501 502 // Reading replication tasks need to be quorum level consistent, otherwise we could lose task 503 query := d.Session.Query(templateGetReplicationTasksQuery, 504 request.ShardID, 505 rowTypeReplicationTask, 506 rowTypeReplicationNamespaceID, 507 rowTypeReplicationWorkflowID, 508 rowTypeReplicationRunID, 509 defaultVisibilityTimestamp, 510 request.InclusiveMinTaskKey.TaskID, 511 request.ExclusiveMaxTaskKey.TaskID, 512 ).WithContext(ctx).PageSize(request.BatchSize).PageState(request.NextPageToken) 513 514 return d.populateGetReplicationTasksResponse(query, "GetReplicationTasks") 515 } 516 517 func (d *MutableStateTaskStore) completeReplicationTask( 518 ctx context.Context, 519 request *p.CompleteHistoryTaskRequest, 520 ) error { 521 query := d.Session.Query(templateCompleteReplicationTaskQuery, 522 request.ShardID, 523 rowTypeReplicationTask, 524 rowTypeReplicationNamespaceID, 525 rowTypeReplicationWorkflowID, 526 rowTypeReplicationRunID, 527 defaultVisibilityTimestamp, 528 request.TaskKey.TaskID, 529 ).WithContext(ctx) 530 531 err := query.Exec() 532 return gocql.ConvertError("CompleteReplicationTask", err) 533 } 534 535 func (d *MutableStateTaskStore) rangeCompleteReplicationTasks( 536 ctx context.Context, 537 request *p.RangeCompleteHistoryTasksRequest, 538 ) error { 539 query := d.Session.Query(templateRangeCompleteReplicationTaskQuery, 540 request.ShardID, 541 rowTypeReplicationTask, 542 rowTypeReplicationNamespaceID, 543 rowTypeReplicationWorkflowID, 544 rowTypeReplicationRunID, 545 defaultVisibilityTimestamp, 546 request.InclusiveMinTaskKey.TaskID, 547 request.ExclusiveMaxTaskKey.TaskID, 548 ).WithContext(ctx) 549 550 err := query.Exec() 551 return gocql.ConvertError("RangeCompleteReplicationTask", err) 552 } 553 554 func (d *MutableStateTaskStore) PutReplicationTaskToDLQ( 555 ctx context.Context, 556 request *p.PutReplicationTaskToDLQRequest, 557 ) error { 558 task := request.TaskInfo 559 datablob, err := serialization.ReplicationTaskInfoToBlob(task) 560 if err != nil { 561 return gocql.ConvertError("PutReplicationTaskToDLQ", err) 562 } 563 564 // Use source cluster name as the workflow id for replication dlq 565 query := d.Session.Query(templateCreateReplicationTaskQuery, 566 request.ShardID, 567 rowTypeDLQ, 568 rowTypeDLQNamespaceID, 569 request.SourceClusterName, 570 rowTypeDLQRunID, 571 datablob.Data, 572 datablob.EncodingType.String(), 573 defaultVisibilityTimestamp, 574 task.GetTaskId(), 575 ).WithContext(ctx) 576 577 err = query.Exec() 578 if err != nil { 579 return gocql.ConvertError("PutReplicationTaskToDLQ", err) 580 } 581 582 return nil 583 } 584 585 func (d *MutableStateTaskStore) GetReplicationTasksFromDLQ( 586 ctx context.Context, 587 request *p.GetReplicationTasksFromDLQRequest, 588 ) (*p.InternalGetHistoryTasksResponse, error) { 589 // Reading replication tasks need to be quorum level consistent, otherwise we could lose tasks 590 query := d.Session.Query(templateGetReplicationTasksQuery, 591 request.ShardID, 592 rowTypeDLQ, 593 rowTypeDLQNamespaceID, 594 request.SourceClusterName, 595 rowTypeDLQRunID, 596 defaultVisibilityTimestamp, 597 request.InclusiveMinTaskKey.TaskID, 598 request.ExclusiveMaxTaskKey.TaskID, 599 ).WithContext(ctx).PageSize(request.BatchSize).PageState(request.NextPageToken) 600 601 return d.populateGetReplicationTasksResponse(query, "GetReplicationTasksFromDLQ") 602 } 603 604 func (d *MutableStateTaskStore) DeleteReplicationTaskFromDLQ( 605 ctx context.Context, 606 request *p.DeleteReplicationTaskFromDLQRequest, 607 ) error { 608 609 query := d.Session.Query(templateCompleteReplicationTaskQuery, 610 request.ShardID, 611 rowTypeDLQ, 612 rowTypeDLQNamespaceID, 613 request.SourceClusterName, 614 rowTypeDLQRunID, 615 defaultVisibilityTimestamp, 616 request.TaskKey.TaskID, 617 ).WithContext(ctx) 618 619 err := query.Exec() 620 return gocql.ConvertError("DeleteReplicationTaskFromDLQ", err) 621 } 622 623 func (d *MutableStateTaskStore) RangeDeleteReplicationTaskFromDLQ( 624 ctx context.Context, 625 request *p.RangeDeleteReplicationTaskFromDLQRequest, 626 ) error { 627 628 query := d.Session.Query(templateRangeCompleteReplicationTaskQuery, 629 request.ShardID, 630 rowTypeDLQ, 631 rowTypeDLQNamespaceID, 632 request.SourceClusterName, 633 rowTypeDLQRunID, 634 defaultVisibilityTimestamp, 635 request.InclusiveMinTaskKey.TaskID, 636 request.ExclusiveMaxTaskKey.TaskID, 637 ).WithContext(ctx) 638 639 err := query.Exec() 640 return gocql.ConvertError("RangeDeleteReplicationTaskFromDLQ", err) 641 } 642 643 func (d *MutableStateTaskStore) IsReplicationDLQEmpty( 644 ctx context.Context, 645 request *p.GetReplicationTasksFromDLQRequest, 646 ) (bool, error) { 647 648 query := d.Session.Query(templateIsQueueEmptyQuery, 649 request.ShardID, 650 rowTypeDLQ, 651 rowTypeDLQNamespaceID, 652 request.SourceClusterName, 653 rowTypeDLQRunID, 654 defaultVisibilityTimestamp, 655 request.InclusiveMinTaskKey.TaskID, 656 ).WithContext(ctx) 657 658 if err := query.Scan(nil); err != nil { 659 if gocql.IsNotFoundError(err) { 660 return true, nil 661 } 662 return true, gocql.ConvertError("IsReplicationDLQEmpty", err) 663 } 664 return false, nil 665 } 666 667 func (d *MutableStateTaskStore) getVisibilityTasks( 668 ctx context.Context, 669 request *p.GetHistoryTasksRequest, 670 ) (*p.InternalGetHistoryTasksResponse, error) { 671 672 // Reading Visibility tasks need to be quorum level consistent, otherwise we could lose task 673 query := d.Session.Query(templateGetVisibilityTasksQuery, 674 request.ShardID, 675 rowTypeVisibilityTask, 676 rowTypeVisibilityTaskNamespaceID, 677 rowTypeVisibilityTaskWorkflowID, 678 rowTypeVisibilityTaskRunID, 679 defaultVisibilityTimestamp, 680 request.InclusiveMinTaskKey.TaskID, 681 request.ExclusiveMaxTaskKey.TaskID, 682 ).WithContext(ctx) 683 iter := query.PageSize(request.BatchSize).PageState(request.NextPageToken).Iter() 684 685 response := &p.InternalGetHistoryTasksResponse{} 686 var taskID int64 687 var data []byte 688 var encoding string 689 690 for iter.Scan(&taskID, &data, &encoding) { 691 response.Tasks = append(response.Tasks, p.InternalHistoryTask{ 692 Key: tasks.NewImmediateKey(taskID), 693 Blob: p.NewDataBlob(data, encoding), 694 }) 695 696 taskID = 0 697 data = nil 698 encoding = "" 699 } 700 if len(iter.PageState()) > 0 { 701 response.NextPageToken = iter.PageState() 702 } 703 704 if err := iter.Close(); err != nil { 705 return nil, gocql.ConvertError("GetVisibilityTasks", err) 706 } 707 708 return response, nil 709 } 710 711 func (d *MutableStateTaskStore) completeVisibilityTask( 712 ctx context.Context, 713 request *p.CompleteHistoryTaskRequest, 714 ) error { 715 query := d.Session.Query(templateCompleteVisibilityTaskQuery, 716 request.ShardID, 717 rowTypeVisibilityTask, 718 rowTypeVisibilityTaskNamespaceID, 719 rowTypeVisibilityTaskWorkflowID, 720 rowTypeVisibilityTaskRunID, 721 defaultVisibilityTimestamp, 722 request.TaskKey.TaskID, 723 ).WithContext(ctx) 724 725 err := query.Exec() 726 return gocql.ConvertError("CompleteVisibilityTask", err) 727 } 728 729 func (d *MutableStateTaskStore) rangeCompleteVisibilityTasks( 730 ctx context.Context, 731 request *p.RangeCompleteHistoryTasksRequest, 732 ) error { 733 query := d.Session.Query(templateRangeCompleteVisibilityTaskQuery, 734 request.ShardID, 735 rowTypeVisibilityTask, 736 rowTypeVisibilityTaskNamespaceID, 737 rowTypeVisibilityTaskWorkflowID, 738 rowTypeVisibilityTaskRunID, 739 defaultVisibilityTimestamp, 740 request.InclusiveMinTaskKey.TaskID, 741 request.ExclusiveMaxTaskKey.TaskID, 742 ).WithContext(ctx) 743 744 err := query.Exec() 745 return gocql.ConvertError("RangeCompleteVisibilityTask", err) 746 } 747 748 func (d *MutableStateTaskStore) populateGetReplicationTasksResponse( 749 query gocql.Query, 750 operation string, 751 ) (*p.InternalGetHistoryTasksResponse, error) { 752 iter := query.Iter() 753 754 response := &p.InternalGetHistoryTasksResponse{} 755 var taskID int64 756 var data []byte 757 var encoding string 758 759 for iter.Scan(&taskID, &data, &encoding) { 760 response.Tasks = append(response.Tasks, p.InternalHistoryTask{ 761 Key: tasks.NewImmediateKey(taskID), 762 Blob: p.NewDataBlob(data, encoding), 763 }) 764 765 taskID = 0 766 data = nil 767 encoding = "" 768 } 769 if len(iter.PageState()) > 0 { 770 response.NextPageToken = iter.PageState() 771 } 772 773 if err := iter.Close(); err != nil { 774 return nil, gocql.ConvertError(operation, err) 775 } 776 777 return response, nil 778 } 779 780 func (d *MutableStateTaskStore) getHistoryTasks( 781 ctx context.Context, 782 request *p.GetHistoryTasksRequest, 783 ) (*p.InternalGetHistoryTasksResponse, error) { 784 switch request.TaskCategory.Type() { 785 case tasks.CategoryTypeImmediate: 786 return d.getHistoryImmedidateTasks(ctx, request) 787 case tasks.CategoryTypeScheduled: 788 return d.getHistoryScheduledTasks(ctx, request) 789 default: 790 panic(fmt.Sprintf("Unknown task category type: %v", request.TaskCategory.Type().String())) 791 } 792 } 793 794 func (d *MutableStateTaskStore) getHistoryImmedidateTasks( 795 ctx context.Context, 796 request *p.GetHistoryTasksRequest, 797 ) (*p.InternalGetHistoryTasksResponse, error) { 798 // execution manager should already validated the request 799 // Reading history tasks need to be quorum level consistent, otherwise we could lose task 800 801 query := d.Session.Query(templateGetHistoryImmediateTasksQuery, 802 request.ShardID, 803 request.TaskCategory.ID(), 804 rowTypeHistoryTaskNamespaceID, 805 rowTypeHistoryTaskWorkflowID, 806 rowTypeHistoryTaskRunID, 807 defaultVisibilityTimestamp, 808 request.InclusiveMinTaskKey.TaskID, 809 request.ExclusiveMaxTaskKey.TaskID, 810 ).WithContext(ctx) 811 812 iter := query.PageSize(request.BatchSize).PageState(request.NextPageToken).Iter() 813 814 response := &p.InternalGetHistoryTasksResponse{} 815 var taskID int64 816 var data []byte 817 var encoding string 818 819 for iter.Scan(&taskID, &data, &encoding) { 820 response.Tasks = append(response.Tasks, p.InternalHistoryTask{ 821 Key: tasks.NewImmediateKey(taskID), 822 Blob: p.NewDataBlob(data, encoding), 823 }) 824 825 taskID = 0 826 data = nil 827 encoding = "" 828 } 829 if len(iter.PageState()) > 0 { 830 response.NextPageToken = iter.PageState() 831 } 832 833 if err := iter.Close(); err != nil { 834 return nil, gocql.ConvertError("GetHistoryImmediateTasks", err) 835 } 836 837 return response, nil 838 } 839 840 func (d *MutableStateTaskStore) getHistoryScheduledTasks( 841 ctx context.Context, 842 request *p.GetHistoryTasksRequest, 843 ) (*p.InternalGetHistoryTasksResponse, error) { 844 // execution manager should already validated the request 845 // Reading history tasks need to be quorum level consistent, otherwise we could lose task 846 847 minTimestamp := p.UnixMilliseconds(request.InclusiveMinTaskKey.FireTime) 848 maxTimestamp := p.UnixMilliseconds(request.ExclusiveMaxTaskKey.FireTime) 849 query := d.Session.Query(templateGetHistoryScheduledTasksQuery, 850 request.ShardID, 851 request.TaskCategory.ID(), 852 rowTypeHistoryTaskNamespaceID, 853 rowTypeHistoryTaskWorkflowID, 854 rowTypeHistoryTaskRunID, 855 minTimestamp, 856 maxTimestamp, 857 ).WithContext(ctx) 858 859 iter := query.PageSize(request.BatchSize).PageState(request.NextPageToken).Iter() 860 861 response := &p.InternalGetHistoryTasksResponse{} 862 var timestamp time.Time 863 var taskID int64 864 var data []byte 865 var encoding string 866 867 for iter.Scan(×tamp, &taskID, &data, &encoding) { 868 response.Tasks = append(response.Tasks, p.InternalHistoryTask{ 869 Key: tasks.NewKey(timestamp, taskID), 870 Blob: p.NewDataBlob(data, encoding), 871 }) 872 873 timestamp = time.Time{} 874 taskID = 0 875 data = nil 876 encoding = "" 877 } 878 if len(iter.PageState()) > 0 { 879 response.NextPageToken = iter.PageState() 880 } 881 882 if err := iter.Close(); err != nil { 883 return nil, gocql.ConvertError("GetHistoryScheduledTasks", err) 884 } 885 886 return response, nil 887 } 888 889 func (d *MutableStateTaskStore) completeHistoryTask( 890 ctx context.Context, 891 request *p.CompleteHistoryTaskRequest, 892 ) error { 893 ts := defaultVisibilityTimestamp 894 if request.TaskCategory.Type() == tasks.CategoryTypeScheduled { 895 ts = p.UnixMilliseconds(request.TaskKey.FireTime) 896 } 897 query := d.Session.Query(templateCompleteHistoryTaskQuery, 898 request.ShardID, 899 request.TaskCategory.ID(), 900 rowTypeHistoryTaskNamespaceID, 901 rowTypeHistoryTaskWorkflowID, 902 rowTypeHistoryTaskRunID, 903 ts, 904 request.TaskKey.TaskID, 905 ).WithContext(ctx) 906 907 err := query.Exec() 908 return gocql.ConvertError("CompleteHistoryTask", err) 909 } 910 911 func (d *MutableStateTaskStore) rangeCompleteHistoryTasks( 912 ctx context.Context, 913 request *p.RangeCompleteHistoryTasksRequest, 914 ) error { 915 // execution manager should already validated the request 916 var query gocql.Query 917 if request.TaskCategory.Type() == tasks.CategoryTypeImmediate { 918 query = d.Session.Query(templateRangeCompleteHistoryImmediateTasksQuery, 919 request.ShardID, 920 request.TaskCategory.ID(), 921 rowTypeHistoryTaskNamespaceID, 922 rowTypeHistoryTaskWorkflowID, 923 rowTypeHistoryTaskRunID, 924 defaultVisibilityTimestamp, 925 request.InclusiveMinTaskKey.TaskID, 926 request.ExclusiveMaxTaskKey.TaskID, 927 ).WithContext(ctx) 928 } else { 929 minTimestamp := p.UnixMilliseconds(request.InclusiveMinTaskKey.FireTime) 930 maxTimestamp := p.UnixMilliseconds(request.ExclusiveMaxTaskKey.FireTime) 931 query = d.Session.Query(templateRangeCompleteHistoryScheduledTasksQuery, 932 request.ShardID, 933 request.TaskCategory.ID(), 934 rowTypeHistoryTaskNamespaceID, 935 rowTypeHistoryTaskWorkflowID, 936 rowTypeHistoryTaskRunID, 937 minTimestamp, 938 maxTimestamp, 939 ).WithContext(ctx) 940 } 941 942 err := query.Exec() 943 return gocql.ConvertError("RangeCompleteHistoryTasks", err) 944 }