Add Timeout and IsTimeoutError functions.

This adds the API for controlling and checking for timeouts.
Timeouts aren't actually implemented yet.

Change-Id: I39f189711a058e255fe30b5a1dce3c7d821483c7
This commit is contained in:
David Symonds 2014-02-03 10:32:22 +11:00
Родитель 351b6899ed
Коммит 4d3336d991
2 изменённых файлов: 108 добавлений и 0 удалений

49
timeout.go Normal file
Просмотреть файл

@ -0,0 +1,49 @@
// Copyright 2013 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package appengine
import (
"time"
"code.google.com/p/goprotobuf/proto"
"github.com/golang/appengine/internal"
)
// IsTimeoutError reports whether err is a timeout error.
func IsTimeoutError(err error) bool {
if t, ok := err.(interface {
IsTimeout() bool
}); ok {
return t.IsTimeout()
}
return false
}
// Timeout returns a replacement context that uses d as the default API RPC timeout.
func Timeout(c Context, d time.Duration) Context {
return &timeoutContext{
Context: c,
d: d,
}
}
type timeoutContext struct {
Context
d time.Duration
}
func (t *timeoutContext) Call(service, method string, in, out proto.Message, opts *internal.CallOptions) error {
// Only affect calls that don't have a timeout.
if opts == nil || opts.Timeout == 0 {
newOpts := new(internal.CallOptions)
if opts != nil {
*newOpts = *opts
}
newOpts.Timeout = t.d
opts = newOpts
}
return t.Context.Call(service, method, in, out, opts)
}

59
timeout_test.go Normal file
Просмотреть файл

@ -0,0 +1,59 @@
// Copyright 2013 Google Inc. All rights reserved.
// Use of this source code is governed by the Apache 2.0
// license that can be found in the LICENSE file.
package appengine
import (
"testing"
"time"
"code.google.com/p/goprotobuf/proto"
"github.com/golang/appengine/internal"
)
type timeoutRecorder struct {
Context
d time.Duration
}
func (tr *timeoutRecorder) Call(_, _ string, _, _ proto.Message, opts *internal.CallOptions) error {
tr.d = 5 * time.Second // default
if opts != nil {
tr.d = opts.Timeout
}
return nil
}
func TestTimeout(t *testing.T) {
tests := []struct {
desc string
opts *internal.CallOptions
want time.Duration
}{
{
"no opts",
nil,
6 * time.Second,
},
{
"empty opts",
&internal.CallOptions{},
6 * time.Second,
},
{
"set opts",
&internal.CallOptions{Timeout: 7 * time.Second},
7 * time.Second,
},
}
for _, test := range tests {
tr := new(timeoutRecorder)
c := Timeout(tr, 6*time.Second)
c.Call("service", "method", nil, nil, test.opts)
if tr.d != test.want {
t.Errorf("%s: timeout was %v, want %v", test.desc, tr.d, test.want)
}
}
}