Files
tasks/service/history/workflow/query.go
zeekay 5a601d081b rebrand: go.temporal.io/server -> github.com/hanzoai/tasks
Full module path rebrand from Temporal to Hanzo Tasks:
- go.mod module: github.com/hanzoai/tasks
- All internal Go imports updated (1906 files)
- cmd/server renamed to cmd/tasksd
- Binary name: tasksd (was temporal-server)
- Docker images: hanzoai/tasks (was temporalio/server)
- README rewritten with Hanzo Tasks branding
- LLM.md created with integration notes
- Makefile, goreleaser, CI workflows updated
- go.temporal.io/sdk and go.temporal.io/api imports preserved (separate repos)

Fork of Temporal.io (MIT license).
2026-03-19 10:36:40 -07:00

124 lines
3.2 KiB
Go

package workflow
import (
"sync/atomic"
"github.com/google/uuid"
enumspb "go.temporal.io/api/enums/v1"
querypb "go.temporal.io/api/query/v1"
"go.temporal.io/api/serviceerror"
historyi "github.com/hanzoai/tasks/service/history/interfaces"
)
const (
QueryCompletionTypeSucceeded historyi.QueryCompletionType = iota
QueryCompletionTypeUnblocked
QueryCompletionTypeFailed
)
var (
errCompletionStateInvalid = serviceerror.NewInternal("query completion state invalid")
errAlreadyInCompletionState = serviceerror.NewInternal("query is already in completion state")
errQueryNotInCompletionState = serviceerror.NewInternal("query is not in completion state")
)
type (
query interface {
getID() string
getCompletionCh() <-chan struct{}
getQueryInput() *querypb.WorkflowQuery
GetCompletionState() (*historyi.QueryCompletionState, error)
setCompletionState(*historyi.QueryCompletionState) error
}
queryImpl struct {
id string
queryInput *querypb.WorkflowQuery
completionCh chan struct{}
completionState atomic.Value
}
)
func newQuery(queryInput *querypb.WorkflowQuery) query {
return &queryImpl{
id: uuid.NewString(),
queryInput: queryInput,
completionCh: make(chan struct{}),
}
}
func (q *queryImpl) getID() string {
return q.id
}
func (q *queryImpl) getCompletionCh() <-chan struct{} {
return q.completionCh
}
func (q *queryImpl) getQueryInput() *querypb.WorkflowQuery {
return q.queryInput
}
func (q *queryImpl) GetCompletionState() (*historyi.QueryCompletionState, error) {
ts := q.completionState.Load()
if ts == nil {
return nil, errQueryNotInCompletionState
}
queryState, ok := ts.(*historyi.QueryCompletionState)
if !ok {
return nil, errCompletionStateInvalid
}
return queryState, nil
}
func (q *queryImpl) setCompletionState(completionState *historyi.QueryCompletionState) error {
if err := q.validateCompletionState(completionState); err != nil {
return err
}
currCompletionState, _ := q.GetCompletionState()
if currCompletionState != nil {
return errAlreadyInCompletionState
}
q.completionState.Store(completionState)
close(q.completionCh)
return nil
}
func (q *queryImpl) validateCompletionState(
completionState *historyi.QueryCompletionState,
) error {
if completionState == nil {
return errCompletionStateInvalid
}
switch completionState.Type {
case QueryCompletionTypeSucceeded:
if completionState.Result == nil || completionState.Err != nil {
return errCompletionStateInvalid
}
queryResult := completionState.Result
validAnswered := queryResult.GetResultType() == enumspb.QUERY_RESULT_TYPE_ANSWERED &&
queryResult.Answer != nil &&
queryResult.GetErrorMessage() == ""
validFailed := queryResult.GetResultType() == enumspb.QUERY_RESULT_TYPE_FAILED &&
queryResult.Answer == nil &&
queryResult.GetErrorMessage() != ""
if !validAnswered && !validFailed {
return errCompletionStateInvalid
}
return nil
case QueryCompletionTypeUnblocked:
if completionState.Result != nil || completionState.Err != nil {
return errCompletionStateInvalid
}
return nil
case QueryCompletionTypeFailed:
if completionState.Result != nil || completionState.Err == nil {
return errCompletionStateInvalid
}
return nil
default:
return errCompletionStateInvalid
}
}