Skip to content

Commit

Permalink
Merge pull request #84 from dhontecillas/merge_incomplete_responses_data
Browse files Browse the repository at this point in the history
Fix #80: Merge incomplete responses data
  • Loading branch information
kpacha committed Feb 1, 2018
2 parents ecba1b3 + 3a38a74 commit eb23565
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 10 deletions.
28 changes: 18 additions & 10 deletions proxy/merging.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,19 +78,27 @@ func requestPart(ctx context.Context, next Proxy, request *Request, out chan<- *
}

func combineData(total int, parts []*Response) *Response {
composedData := make(map[string]interface{})
isComplete := len(parts) == total

var isComplete bool = len(parts) == total
var retResponse *Response = nil
for _, part := range parts {
if part != nil && part.IsComplete {
for k, v := range part.Data {
composedData[k] = v
}
isComplete = isComplete && part.IsComplete
} else {
if part == nil || part.Data == nil {
isComplete = false
continue
}
isComplete = isComplete && part.IsComplete
if retResponse == nil {
retResponse = part
continue
}
for k, v := range part.Data {
retResponse.Data[k] = v
}
}

return &Response{Data: composedData, IsComplete: isComplete}
if nil == retResponse {
// do not allow nil data in the response:
return &Response{Data: make(map[string]interface{}, 0), IsComplete: isComplete}
}
retResponse.IsComplete = isComplete
return retResponse
}
66 changes: 66 additions & 0 deletions proxy/merging_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,72 @@ func TestNewMergeDataMiddleware_ok(t *testing.T) {
}
}

func TestNewMergeDataMiddleware_mergeIncompleteResults(t *testing.T) {
timeout := 500
backend := config.Backend{}
endpoint := config.EndpointConfig{
Backend: []*config.Backend{&backend, &backend},
Timeout: time.Duration(timeout) * time.Millisecond,
}
mw := NewMergeDataMiddleware(&endpoint)
p := mw(
dummyProxy(&Response{Data: map[string]interface{}{"supu": 42}, IsComplete: true}),
dummyProxy(&Response{Data: map[string]interface{}{"tupu": true}, IsComplete: false}))
mustEnd := time.After(time.Duration(2*timeout) * time.Millisecond)
out, err := p(context.Background(), &Request{})
if err != nil {
t.Errorf("The middleware propagated an unexpected error: %s\n", err.Error())
}
if out == nil {
t.Errorf("The proxy returned a null result\n")
return
}
select {
case <-mustEnd:
t.Errorf("We were expecting a response but we got none\n")
default:
if len(out.Data) != 2 {
t.Errorf("We were expecting incomplete results merged but we got %v!\n", out)
}
if out.IsComplete {
t.Errorf("We were expecting an incomplete response but we got an incompleted one!\n")
}
}
}

func TestNewMergeDataMiddleware_mergeEmptyResults(t *testing.T) {
timeout := 500
backend := config.Backend{}
endpoint := config.EndpointConfig{
Backend: []*config.Backend{&backend, &backend},
Timeout: time.Duration(timeout) * time.Millisecond,
}
mw := NewMergeDataMiddleware(&endpoint)
p := mw(
dummyProxy(&Response{Data: nil, IsComplete: false}),
dummyProxy(&Response{Data: nil, IsComplete: false}))
mustEnd := time.After(time.Duration(2*timeout) * time.Millisecond)
out, err := p(context.Background(), &Request{})
if err != nil {
t.Errorf("The middleware propagated an unexpected error: %s\n", err.Error())
}
if out == nil {
t.Errorf("The proxy returned a null result\n")
return
}
select {
case <-mustEnd:
t.Errorf("We were expecting a response but we got none\n")
default:
if len(out.Data) != 0 {
t.Errorf("We were expecting empty data but we got %v!\n", out)
}
if out.IsComplete {
t.Errorf("We were expecting an incomplete response but we got an incompleted one!\n")
}
}
}

func TestNewMergeDataMiddleware_partialTimeout(t *testing.T) {
timeout := 100
backend := config.Backend{Timeout: time.Duration(timeout) * time.Millisecond}
Expand Down

0 comments on commit eb23565

Please sign in to comment.