Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type ClientInterface interface {
IsHealthy() bool
GetTask(taskUID int64) (resp *Task, err error)
GetTasks(param *TasksQuery) (resp *TaskResult, err error)
CancelTasks(param *TasksQuery) (resp *TaskInfo, err error)
WaitForTask(taskUID int64, options ...WaitParams) (*Task, error)
GenerateTenantToken(APIKeyUID string, searchRules map[string]interface{}, options *TenantTokenOptions) (resp string, err error)
}
Expand Down Expand Up @@ -285,6 +286,26 @@ func (c *Client) GetTasks(param *TasksQuery) (resp *TaskResult, err error) {
return resp, nil
}

func (c *Client) CancelTasks(param *TasksQuery) (resp *TaskInfo, err error) {
resp = &TaskInfo{}
req := internalRequest{
endpoint: "/tasks/cancel",
method: http.MethodPost,
withRequest: nil,
withResponse: &resp,
withQueryParams: map[string]string{},
acceptedStatusCodes: []int{http.StatusOK},
functionName: "CancelTasks",
}
if param != nil {
encodeTasksQuery(param, &req)
}
if err := c.executeRequest(req); err != nil {
return nil, err
}
return resp, nil
}

// WaitForTask waits for a task to be processed
//
// The function will check by regular interval provided in parameter interval
Expand Down
134 changes: 132 additions & 2 deletions client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package meilisearch

import (
"context"
"strings"

"sync"
"testing"
"time"
Expand Down Expand Up @@ -655,8 +657,8 @@ func TestClient_GetTask(t *testing.T) {
require.GreaterOrEqual(t, gotResp.UID, tt.args.taskUID)
require.Equal(t, tt.args.UID, gotResp.IndexUID)
require.Equal(t, TaskStatusSucceeded, gotResp.Status)
require.Equal(t, len(tt.args.document), gotResp.Details.ReceivedDocuments)
require.Equal(t, len(tt.args.document), gotResp.Details.IndexedDocuments)
require.Equal(t, int64(len(tt.args.document)), gotResp.Details.ReceivedDocuments)
require.Equal(t, int64(len(tt.args.document)), gotResp.Details.IndexedDocuments)

// Make sure that timestamps are also retrieved
require.NotZero(t, gotResp.EnqueuedAt)
Expand Down Expand Up @@ -827,6 +829,134 @@ func TestClient_GetTasks(t *testing.T) {
}
}

func TestClient_CancelTasks(t *testing.T) {
type args struct {
UID string
client *Client
query *TasksQuery
}
tests := []struct {
name string
args args
want string
}{
{
name: "TestBasicCancelTasks",
args: args{
UID: "indexUID",
client: defaultClient,
query: &TasksQuery{
Statuses: []string{"succeeded"},
},
},
want: "?statuses=succeeded",
},
{
name: "TestCancelTasksWithIndexUidFilter",
args: args{
UID: "indexUID",
client: defaultClient,
query: &TasksQuery{
IndexUIDS: []string{"0"},
},
},
want: "?indexUids=0",
},
{
name: "TestCancelTasksWithMultipleIndexUidsFilter",
args: args{
UID: "indexUID",
client: defaultClient,
query: &TasksQuery{
IndexUIDS: []string{"0", "1"},
},
},
want: "?indexUids=0%2C1",
},
{
name: "TestCancelTasksWithUidFilter",
args: args{
UID: "indexUID",
client: defaultClient,
query: &TasksQuery{
UIDS: []int64{0},
},
},
want: "?uids=0",
},
{
name: "TestCancelTasksWithMultipleUidsFilter",
args: args{
UID: "indexUID",
client: defaultClient,
query: &TasksQuery{
UIDS: []int64{0, 1},
},
},
want: "?uids=0%2C1",
},
{
name: "TestCancelTasksWithDateFilter",
args: args{
UID: "indexUID",
client: defaultClient,
query: &TasksQuery{
BeforeEnqueuedAt: time.Now(),
},
},
want: strings.NewReplacer(":", "%3A").Replace("?beforeEnqueuedAt=" + time.Now().Format("2006-01-02T15:04:05Z")),
},
{
name: "TestCancelTasksWithCanceledByFilter",
args: args{
UID: "indexUID",
client: defaultClient,
query: &TasksQuery{
CanceledBy: []int64{1},
},
},
want: "?canceledBy=1",
},
{
name: "TestCancelTasksWithParameters",
args: args{
UID: "indexUID",
client: defaultClient,
query: &TasksQuery{
Statuses: []string{"enqueued"},
IndexUIDS: []string{"indexUID"},
UIDS: []int64{1},
AfterEnqueuedAt: time.Now(),
},
},
want: "?afterEnqueuedAt=" + strings.NewReplacer(":", "%3A").Replace(time.Now().Format("2006-01-02T15:04:05Z")) + "&indexUids=indexUID&statuses=enqueued&uids=1",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := tt.args.client
t.Cleanup(cleanup(c))

gotResp, err := c.CancelTasks(tt.args.query)
require.NoError(t, err)

_, err = c.WaitForTask(gotResp.TaskUID)
require.NoError(t, err)

gotTask, err := c.GetTask(gotResp.TaskUID)
require.NoError(t, err)

require.NotNil(t, gotResp.Status)
require.NotNil(t, gotResp.Type)
require.NotNil(t, gotResp.TaskUID)
require.NotNil(t, gotResp.EnqueuedAt)
require.Equal(t, "", gotResp.IndexUID)
require.Equal(t, "taskCancelation", gotResp.Type)
require.Equal(t, tt.want, gotTask.Details.OriginalFilter)
})
}
}

func TestClient_DefaultWaitForTask(t *testing.T) {
type args struct {
UID string
Expand Down
33 changes: 20 additions & 13 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,22 +130,18 @@ type Task struct {
StartedAt time.Time `json:"startedAt,omitempty"`
FinishedAt time.Time `json:"finishedAt,omitempty"`
Details Details `json:"details,omitempty"`
CanceledBy int64 `json:"canceledBy,omitempty"`
}

// TaskInfo indicates information regarding a task returned by an asynchronous method
//
// Documentation: https://docs.meilisearch.com/reference/api/tasks.html#tasks
type TaskInfo struct {
Status TaskStatus `json:"status"`
TaskUID int64 `json:"taskUid,omitempty"`
IndexUID string `json:"indexUid"`
Type string `json:"type"`
Error meilisearchApiError `json:"error,omitempty"`
Duration string `json:"duration,omitempty"`
EnqueuedAt time.Time `json:"enqueuedAt"`
StartedAt time.Time `json:"startedAt,omitempty"`
FinishedAt time.Time `json:"finishedAt,omitempty"`
Details Details `json:"details,omitempty"`
Status TaskStatus `json:"status"`
TaskUID int64 `json:"taskUid"`
IndexUID string `json:"indexUid"`
Type string `json:"type"`
EnqueuedAt time.Time `json:"enqueuedAt"`
}

// TasksQuery is the request body for list documents method
Expand All @@ -166,15 +162,26 @@ type TasksQuery struct {
}

type Details struct {
ReceivedDocuments int `json:"receivedDocuments,omitempty"`
IndexedDocuments int `json:"indexedDocuments,omitempty"`
DeletedDocuments int `json:"deletedDocuments,omitempty"`
ReceivedDocuments int64 `json:"receivedDocuments,omitempty"`
IndexedDocuments int64 `json:"indexedDocuments,omitempty"`
DeletedDocuments int64 `json:"deletedDocuments,omitempty"`
PrimaryKey string `json:"primaryKey,omitempty"`
ProvidedIds int64 `json:"providedIds,omitempty"`
RankingRules []string `json:"rankingRules,omitempty"`
DistinctAttribute *string `json:"distinctAttribute,omitempty"`
SearchableAttributes []string `json:"searchableAttributes,omitempty"`
DisplayedAttributes []string `json:"displayedAttributes,omitempty"`
StopWords []string `json:"stopWords,omitempty"`
Synonyms map[string][]string `json:"synonyms,omitempty"`
FilterableAttributes []string `json:"filterableAttributes,omitempty"`
SortableAttributes []string `json:"sortableAttributes,omitempty"`
TypoTolerance *TypoTolerance `json:"typoTolerance,omitempty"`
Pagination *Pagination `json:"pagination,omitempty"`
Faceting *Faceting `json:"faceting,omitempty"`
MatchedTasks int64 `json:"matchedTasks,omitempty"`
CanceledTasks int64 `json:"canceledTasks,omitempty"`
DeletedTasks int64 `json:"deletedTasks,omitempty"`
OriginalFilter string `json:"originalFilter,omitempty"`
}

// Return of multiple tasks is wrap in a TaskResult
Expand Down
Loading