Skip to content

Commit

Permalink
Better task support
Browse files Browse the repository at this point in the history
  • Loading branch information
GeorgeErickson committed Jul 31, 2015
1 parent 2d29b8f commit 19794c6
Show file tree
Hide file tree
Showing 8 changed files with 108 additions and 41 deletions.
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
setup:
go get github.com/sasha-s/goimpl/cmd/goimpl

watch:
ginkgo watch -r -notify -cover -succinct
5 changes: 4 additions & 1 deletion algolia/algolia.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ type Index interface {
Must() *MustIndex
GetTaskStatus(id int64) (*TaskStatus, error)
UpdateObject(Indexable) (*Task, error)
BatchUpdate([]Indexable) (*BatchTask, error)
BatchUpdate([]Indexable) (*Task, error)
GetObject(id string, attrs ...string) Value
Settings() *SettingsBuilder
SetSettings(*Settings) (*Task, error)
Expand All @@ -38,6 +38,9 @@ func New(appId, apiKey string, useMock ...bool) Client {
return NewClientService(appId, apiKey)
}

// FromEnv creates a new Client
// The environment variables `ALGOLIA_APP_ID` and `ALGOLIA_API_KEY` are used.
// If useMock is true the client is a fake algolia implementation.
func FromEnv(useMock ...bool) Client {
return New(env.MustGet("ALGOLIA_APP_ID"), env.MustGet("ALGOLIA_API_KEY"), useMock...)
}
14 changes: 4 additions & 10 deletions algolia/algolia_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ package algolia_test
import (
"github.com/drinkin/di/random"
"github.com/drinkin/go-algolia/algolia"
"github.com/k0kubun/pp"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"
)
Expand All @@ -18,18 +17,13 @@ var _ = Describe("Algolia", func() {
})

CheckValidIndex := func(idx algolia.Index) {
expectTaskPublished := func(taskId int64) {
Eventually(func() bool {
return idx.Must().GetTaskStatus(taskId).IsPublished()
}, 1, .1).Should(BeTrue())
}

It("", func() {
tr, err := idx.UpdateObject(example)
Expect(err).ToNot(HaveOccurred())
Expect(tr.ObjectId).To(Equal(example.AlgoliaId()))

expectTaskPublished(tr.TaskId)
err = tr.Wait()
Expect(err).ToNot(HaveOccurred())

savedObj := new(Example)
Expect(idx.GetObject(example.AlgoliaId()).Scan(savedObj)).ToNot(HaveOccurred())
Expand All @@ -48,8 +42,8 @@ var _ = Describe("Algolia", func() {

It("GetTaskStatus that doesn't exist", func() {
ts, err := idx.GetTaskStatus(random.Int64(1, 99999999999))
pp.Print(ts)
pp.Print(err)
Expect(err).ToNot(HaveOccurred())
Expect(ts.Status).To(Equal("notPublished"))
})

}
Expand Down
20 changes: 7 additions & 13 deletions algolia/index_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"encoding/json"
"sync"
"time"

"github.com/drinkin/di/random"
)

type MockValue struct {
Expand Down Expand Up @@ -74,24 +72,20 @@ func (idx *IndexMock) UpdateObject(obj Indexable) (*Task, error) {
return nil, err
}

task := &Task{
TaskId: random.Int64(1, 9999999999),
ObjectId: obj.AlgoliaId(),
UpdatedAt: time.Now(),
}
task := randomTask(idx)
task.ObjectId = obj.AlgoliaId()
task.UpdatedAt = time.Now()

idx.tasks[task.TaskId] = true
idx.tasks[task.Id] = true

return task, nil
}

func (idx *IndexMock) BatchUpdate(objs []Indexable) (*BatchTask, error) {
func (idx *IndexMock) BatchUpdate(objs []Indexable) (*Task, error) {
idx.mu.Lock()
defer idx.mu.Unlock()

task := &BatchTask{
TaskId: random.Int64(1, 9999999999),
}
task := randomTask(idx)
for _, obj := range objs {
idx.doUpdate(obj)
task.ObjectIds = append(task.ObjectIds, obj.AlgoliaId())
Expand Down Expand Up @@ -119,7 +113,7 @@ func (idx *IndexMock) SetSettings(s *Settings) (*Task, error) {
defer idx.mu.Unlock()

idx.settings = s
return nil, nil
return randomTask(idx), nil
}

func (idx *IndexMock) Settings() *SettingsBuilder {
Expand Down
17 changes: 9 additions & 8 deletions algolia/index_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,12 @@ func (idx *IndexService) GetTaskStatus(taskId int64) (*TaskStatus, error) {

func (idx *IndexService) UpdateObject(obj Indexable) (*Task, error) {
obj.AlgoliaBeforeIndex()
tr := new(Task)
return tr, idx.service.Put(idx.pathFor(obj.AlgoliaId()), obj).Scan(tr)
v := idx.service.Put(idx.pathFor(obj.AlgoliaId()), obj)

return NewTask(idx, v)
}

func (idx *IndexService) BatchUpdate(objs []Indexable) (*BatchTask, error) {
func (idx *IndexService) BatchUpdate(objs []Indexable) (*Task, error) {
requests := make([]*BatchItem, len(objs))

for i, obj := range objs {
Expand All @@ -45,20 +46,20 @@ func (idx *IndexService) BatchUpdate(objs []Indexable) (*BatchTask, error) {
Body: obj,
}
}
tr := new(BatchTask)
return tr, idx.service.Post(idx.pathFor("batch"), map[string]interface{}{
v := idx.service.Post(idx.pathFor("batch"), map[string]interface{}{
"requests": requests,
}).Scan(tr)
})

return NewTask(idx, v)
}

func (idx *IndexService) GetObject(id string, attrs ...string) Value {
return idx.service.Get(idx.pathFor(id))
}

func (idx *IndexService) SetSettings(s *Settings) (*Task, error) {
tr := new(Task)
return tr, idx.service.Put(idx.pathFor("settings"), s).Scan(tr)
v := idx.service.Put(idx.pathFor("settings"), s)
return NewTask(idx, v)
}

func (idx *IndexService) Settings() *SettingsBuilder {
Expand Down
2 changes: 1 addition & 1 deletion algolia/must_index.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ type MustIndex struct {
index Index
}

func (m *MustIndex) BatchUpdate(objs []Indexable) *BatchTask {
func (m *MustIndex) BatchUpdate(objs []Indexable) *Task {
ts, err := m.index.BatchUpdate(objs)
check(err)
return ts
Expand Down
78 changes: 71 additions & 7 deletions algolia/tasks.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
package algolia

import "time"
import (
"fmt"
"time"

"github.com/drinkin/di/random"
)

type TaskStatus struct {
Status string `json:"status"`
Expand All @@ -11,13 +16,72 @@ func (ts *TaskStatus) IsPublished() bool {
return ts.Status == "published"
}

type BatchTask struct {
TaskId int64 `json:"taskID"`
ObjectIds []string `json:"objectIDs"`
}

// Task represents an algolia task response
type Task struct {
TaskId int64 `json:"taskID"`
Id int64 `json:"taskID"`
ObjectId string `json:"ObjectId"`
ObjectIds []string `json:"objectIDs"`
UpdatedAt time.Time `json:"updatedAt"`

index Index
}

// Wait blocks until task status = "published"
func (t *Task) Wait() error {
// check first
isPub, err := t.IsPublished()
if err != nil {
return err
}
if isPub {
return nil
}

pollingInterval := time.Millisecond * 100
timeout := time.After(3 * time.Second)
for {
select {
case <-time.After(pollingInterval):
isPub, err := t.IsPublished()
if err != nil {
return err
}
if isPub {
return nil
}
case <-timeout:
return fmt.Errorf("Wait timeout")
}
}
}

// IsPublished hits the algolia api to check if the task is published
func (t *Task) IsPublished() (bool, error) {
status, err := t.GetStatus()
if err != nil {
return false, err
}

return status.IsPublished(), nil
}

// GetStatus checks
func (t *Task) GetStatus() (*TaskStatus, error) {
return t.index.GetTaskStatus(t.Id)
}

func randomTask(idx Index) *Task {
return &Task{
Id: random.Int64(1, 9999999999),
index: idx,
}

}

func NewTask(idx Index, v Value) (*Task, error) {
task := &Task{
index: idx,
}

return task, v.Scan(task)
}
10 changes: 9 additions & 1 deletion algolia/util.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
package algolia

import "fmt"
import (
"fmt"
"strconv"
)

// Int64ToString is a utility to convert int64 to objectID string
func Int64ToString(v int64) string {
return strconv.FormatInt(v, 10)
}

func HostsForAppId(appId string) []string {
hosts := make([]string, 3)
Expand Down

0 comments on commit 19794c6

Please sign in to comment.