Skip to content

Commit 4784b55

Browse files
DerekBumoleg-jukovec
authored andcommitted
api: change Response type to interface
This commit creates a new `Response` interface. But still, only one `Response` implementation exists: `ConnResponse`. Custom responses (including mocks) are expected to implement this interface. Create a `Response` interface and its implementation `ConnResponse`. For the `Future` method `Get` now returns response data. To get the actual response new method `GetResponse` is added. `IsPush()` method is added to the response iterator. It returns the information if the current response is a `Push`. Right now it does not have a lot of usage, but it will be crucial once we create a separate response for pushes. Part of #237
1 parent 7ce2784 commit 4784b55

38 files changed

+1374
-1603
lines changed

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
2828
in requests instead of their IDs.
2929
- `GetSchema` function to get the actual schema (#7)
3030
- Support connection via an existing socket fd (#321)
31+
- `Header` struct for the response header (#237). It can be accessed via
32+
`Header()` method of the `Response` interface.
3133

3234
### Changed
3335

@@ -67,6 +69,13 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
6769
it (#321)
6870
- Rename `pool.GetPoolInfo` to `pool.GetInfo`. Change return type to
6971
`map[string]ConnectionInfo` (#321)
72+
- `Response` is now an interface (#237)
73+
- All responses are now implementations of the `Response` interface (#237)
74+
- `IsPush()` method is added to the response iterator (#237). It returns
75+
the information if the current response is a `PushResponse`.
76+
`PushCode` constant is removed.
77+
- Method `Get` for `Future` now returns response data (#237). To get the actual
78+
response new `GetResponse` method has been added.
7079

7180
### Deprecated
7281

@@ -89,6 +98,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
8998
- IPROTO constants (#158)
9099
- Code() method from the Request interface (#158)
91100
- `Schema` field from the `Connection` struct (#7)
101+
- `PushCode` constant (#237)
92102

93103
### Fixed
94104

README.md

+19-3
Original file line numberDiff line numberDiff line change
@@ -128,12 +128,13 @@ func main() {
128128
if err != nil {
129129
fmt.Println("Connection refused:", err)
130130
}
131-
resp, err := conn.Do(tarantool.NewInsertRequest(999).
131+
data, err := conn.Do(tarantool.NewInsertRequest(999).
132132
Tuple([]interface{}{99999, "BB"}),
133133
).Get()
134134
if err != nil {
135135
fmt.Println("Error", err)
136-
fmt.Println("Code", resp.Code)
136+
} else {
137+
fmt.Printf("Data: %v", data)
137138
}
138139
}
139140
```
@@ -241,7 +242,9 @@ of the requests is an array instead of array of arrays.
241242

242243
#### IPROTO constants
243244

244-
IPROTO constants have been moved to a separate package [go-iproto](https://github.com/tarantool/go-iproto).
245+
* IPROTO constants have been moved to a separate package [go-iproto](https://github.com/tarantool/go-iproto).
246+
* `PushCode` constant is removed. To check whether the current response is
247+
a push response, use `IsPush()` method of the response iterator instead.
245248

246249
#### Request changes
247250

@@ -255,6 +258,19 @@ needs to be passed instead.
255258
* `UpdateRequest` and `UpsertRequest` structs no longer accept `interface{}`
256259
for an `ops` field. `*Operations` needs to be used instead.
257260

261+
#### Response changes
262+
263+
* `Response` is now an interface.
264+
* Response header stored in a new `Header` struct. It could be accessed via
265+
`Header()` method.
266+
* `ResponseIterator` interface now has `IsPush()` method.
267+
It returns true if the current response is a push response.
268+
269+
#### Future changes
270+
271+
* Method `Get` now returns response data instead of the actual response.
272+
* New method `GetResponse` added to get an actual response.
273+
258274
#### Connect function
259275

260276
`connection.Connect` no longer return non-working connection objects. This function

box_error_test.go

+11-7
Original file line numberDiff line numberDiff line change
@@ -306,9 +306,11 @@ func TestErrorTypeEval(t *testing.T) {
306306
t.Run(name, func(t *testing.T) {
307307
resp, err := conn.Eval("return ...", []interface{}{&testcase.tuple.val})
308308
require.Nil(t, err)
309-
require.NotNil(t, resp.Data)
310-
require.Equal(t, len(resp.Data), 1)
311-
actual, ok := resp.Data[0].(*BoxError)
309+
data, err := resp.Decode()
310+
require.Nil(t, err)
311+
require.NotNil(t, data)
312+
require.Equal(t, len(data), 1)
313+
actual, ok := data[0].(*BoxError)
312314
require.Truef(t, ok, "Response data has valid type")
313315
require.Equal(t, testcase.tuple.val, *actual)
314316
})
@@ -436,15 +438,17 @@ func TestErrorTypeSelect(t *testing.T) {
436438
_, err := conn.Eval(insertEval, []interface{}{})
437439
require.Nilf(t, err, "Tuple has been successfully inserted")
438440

439-
var resp *Response
441+
var resp Response
440442
var offset uint32 = 0
441443
var limit uint32 = 1
442444
resp, err = conn.Select(space, index, offset, limit, IterEq,
443445
[]interface{}{testcase.tuple.pk})
444446
require.Nil(t, err)
445-
require.NotNil(t, resp.Data)
446-
require.Equalf(t, len(resp.Data), 1, "Exactly one tuple had been found")
447-
tpl, ok := resp.Data[0].([]interface{})
447+
data, err := resp.Decode()
448+
require.Nil(t, err)
449+
require.NotNil(t, data)
450+
require.Equalf(t, len(data), 1, "Exactly one tuple had been found")
451+
tpl, ok := data[0].([]interface{})
448452
require.Truef(t, ok, "Tuple has valid type")
449453
require.Equal(t, testcase.tuple.pk, tpl[0])
450454
actual, ok := tpl[1].(*BoxError)

connection.go

+12-14
Original file line numberDiff line numberDiff line change
@@ -97,9 +97,9 @@ func (d defaultLogger) Report(event ConnLogKind, conn *Connection, v ...interfac
9797
log.Printf("tarantool: last reconnect to %s failed: %s, giving it up",
9898
conn.Addr(), err)
9999
case LogUnexpectedResultId:
100-
resp := v[0].(*Response)
100+
header := v[0].(Header)
101101
log.Printf("tarantool: connection %s got unexpected resultId (%d) in response",
102-
conn.Addr(), resp.RequestId)
102+
conn.Addr(), header.RequestId)
103103
case LogWatchEventReadFailed:
104104
err := v[0].(error)
105105
log.Printf("tarantool: unable to parse watch event: %s", err)
@@ -807,8 +807,8 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
807807
conn.reconnect(err, c)
808808
return
809809
}
810-
resp := &Response{buf: smallBuf{b: respBytes}}
811-
err = resp.decodeHeader(conn.dec)
810+
buf := smallBuf{b: respBytes}
811+
header, err := decodeHeader(conn.dec, &buf)
812812
if err != nil {
813813
err = ClientError{
814814
ErrProtocolError,
@@ -818,8 +818,9 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
818818
return
819819
}
820820

821+
resp := &ConnResponse{header: header, buf: buf}
821822
var fut *Future = nil
822-
if iproto.Type(resp.Code) == iproto.IPROTO_EVENT {
823+
if iproto.Type(header.Code) == iproto.IPROTO_EVENT {
823824
if event, err := readWatchEvent(&resp.buf); err == nil {
824825
events <- event
825826
} else {
@@ -830,19 +831,19 @@ func (conn *Connection) reader(r io.Reader, c Conn) {
830831
conn.opts.Logger.Report(LogWatchEventReadFailed, conn, err)
831832
}
832833
continue
833-
} else if resp.Code == PushCode {
834-
if fut = conn.peekFuture(resp.RequestId); fut != nil {
834+
} else if header.Code == uint32(iproto.IPROTO_CHUNK) {
835+
if fut = conn.peekFuture(header.RequestId); fut != nil {
835836
fut.AppendPush(resp)
836837
}
837838
} else {
838-
if fut = conn.fetchFuture(resp.RequestId); fut != nil {
839+
if fut = conn.fetchFuture(header.RequestId); fut != nil {
839840
fut.SetResponse(resp)
840841
conn.markDone(fut)
841842
}
842843
}
843844

844845
if fut == nil {
845-
conn.opts.Logger.Report(LogUnexpectedResultId, conn, resp)
846+
conn.opts.Logger.Report(LogUnexpectedResultId, conn, header)
846847
}
847848
}
848849
}
@@ -1052,10 +1053,7 @@ func (conn *Connection) putFuture(fut *Future, req Request, streamId uint64) {
10521053

10531054
if req.Async() {
10541055
if fut = conn.fetchFuture(reqid); fut != nil {
1055-
resp := &Response{
1056-
RequestId: reqid,
1057-
Code: OkCode,
1058-
}
1056+
resp := &ConnResponse{}
10591057
fut.SetResponse(resp)
10601058
conn.markDone(fut)
10611059
}
@@ -1236,7 +1234,7 @@ func (conn *Connection) SetSchema(s Schema) {
12361234
// NewPrepared passes a sql statement to Tarantool for preparation synchronously.
12371235
func (conn *Connection) NewPrepared(expr string) (*Prepared, error) {
12381236
req := NewPrepareRequest(expr)
1239-
resp, err := conn.Do(req).Get()
1237+
resp, err := conn.Do(req).GetResponse()
12401238
if err != nil {
12411239
return nil, err
12421240
}

connector.go

+12-12
Original file line numberDiff line numberDiff line change
@@ -13,41 +13,41 @@ type Connector interface {
1313

1414
// Deprecated: the method will be removed in the next major version,
1515
// use a PingRequest object + Do() instead.
16-
Ping() (*Response, error)
16+
Ping() (Response, error)
1717
// Deprecated: the method will be removed in the next major version,
1818
// use a SelectRequest object + Do() instead.
1919
Select(space, index interface{}, offset, limit uint32, iterator Iter,
20-
key interface{}) (*Response, error)
20+
key interface{}) (Response, error)
2121
// Deprecated: the method will be removed in the next major version,
2222
// use an InsertRequest object + Do() instead.
23-
Insert(space interface{}, tuple interface{}) (*Response, error)
23+
Insert(space interface{}, tuple interface{}) (Response, error)
2424
// Deprecated: the method will be removed in the next major version,
2525
// use a ReplicaRequest object + Do() instead.
26-
Replace(space interface{}, tuple interface{}) (*Response, error)
26+
Replace(space interface{}, tuple interface{}) (Response, error)
2727
// Deprecated: the method will be removed in the next major version,
2828
// use a DeleteRequest object + Do() instead.
29-
Delete(space, index interface{}, key interface{}) (*Response, error)
29+
Delete(space, index interface{}, key interface{}) (Response, error)
3030
// Deprecated: the method will be removed in the next major version,
3131
// use a UpdateRequest object + Do() instead.
32-
Update(space, index interface{}, key interface{}, ops *Operations) (*Response, error)
32+
Update(space, index interface{}, key interface{}, ops *Operations) (Response, error)
3333
// Deprecated: the method will be removed in the next major version,
3434
// use a UpsertRequest object + Do() instead.
35-
Upsert(space interface{}, tuple interface{}, ops *Operations) (*Response, error)
35+
Upsert(space interface{}, tuple interface{}, ops *Operations) (Response, error)
3636
// Deprecated: the method will be removed in the next major version,
3737
// use a CallRequest object + Do() instead.
38-
Call(functionName string, args interface{}) (*Response, error)
38+
Call(functionName string, args interface{}) (Response, error)
3939
// Deprecated: the method will be removed in the next major version,
4040
// use a Call16Request object + Do() instead.
41-
Call16(functionName string, args interface{}) (*Response, error)
41+
Call16(functionName string, args interface{}) (Response, error)
4242
// Deprecated: the method will be removed in the next major version,
4343
// use a Call17Request object + Do() instead.
44-
Call17(functionName string, args interface{}) (*Response, error)
44+
Call17(functionName string, args interface{}) (Response, error)
4545
// Deprecated: the method will be removed in the next major version,
4646
// use an EvalRequest object + Do() instead.
47-
Eval(expr string, args interface{}) (*Response, error)
47+
Eval(expr string, args interface{}) (Response, error)
4848
// Deprecated: the method will be removed in the next major version,
4949
// use an ExecuteRequest object + Do() instead.
50-
Execute(expr string, args interface{}) (*Response, error)
50+
Execute(expr string, args interface{}) (Response, error)
5151

5252
// Deprecated: the method will be removed in the next major version,
5353
// use a SelectRequest object + Do() instead.

const.go

+1-2
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,5 @@ const (
99
)
1010

1111
const (
12-
OkCode = uint32(iproto.IPROTO_OK)
13-
PushCode = uint32(iproto.IPROTO_CHUNK)
12+
OkCode = uint32(iproto.IPROTO_OK)
1413
)

0 commit comments

Comments
 (0)