Skip to content

Commit bac0680

Browse files
committed
api: create a Response interface
This commit creates a new `Response` interface. But still, only one `Response` implementation exists: `ConnResponse`. But this change will make it easier to create custom responses (mocks as well). 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. All deprecated asynchronous requests operations on a `Connector` return response data instead of an actual responses. All deprecated asynchronous requests operations on a `Pooler` return response data instead of an actual responses. Part of #237
1 parent 7d73f6a commit bac0680

34 files changed

+1307
-1639
lines changed

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+
respHeader := v[0].(header)
101101
log.Printf("tarantool: connection %s got unexpected resultId (%d) in response",
102-
conn.Addr(), resp.RequestId)
102+
conn.Addr(), respHeader.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+
respHeader, 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: respHeader, buf: buf}
821822
var fut *Future = nil
822-
if iproto.Type(resp.Code) == iproto.IPROTO_EVENT {
823+
if iproto.Type(respHeader.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 respHeader.code == PushCode {
835+
if fut = conn.peekFuture(respHeader.requestId); fut != nil {
835836
fut.AppendPush(resp)
836837
}
837838
} else {
838-
if fut = conn.fetchFuture(resp.RequestId); fut != nil {
839+
if fut = conn.fetchFuture(respHeader.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, respHeader)
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.

crud/tarantool_test.go

+28-35
Original file line numberDiff line numberDiff line change
@@ -517,39 +517,32 @@ func testSelectGeneratedData(t *testing.T, conn tarantool.Connector,
517517
Limit(20).
518518
Iterator(tarantool.IterGe).
519519
Key([]interface{}{uint(1010)})
520-
resp, err := conn.Do(req).Get()
520+
data, err := conn.Do(req).Get()
521521
if err != nil {
522522
t.Fatalf("Failed to Select: %s", err.Error())
523523
}
524-
if resp == nil {
525-
t.Fatalf("Response is nil after Select")
526-
}
527-
if len(resp.Data) != expectedTuplesCount {
528-
t.Fatalf("Response Data len %d != %d", len(resp.Data), expectedTuplesCount)
524+
if len(data) != expectedTuplesCount {
525+
t.Fatalf("Response Data len %d != %d", len(data), expectedTuplesCount)
529526
}
530527
}
531528

532529
func testCrudRequestCheck(t *testing.T, req tarantool.Request,
533-
resp *tarantool.Response, err error, expectedLen int) {
530+
data []interface{}, err error, expectedLen int) {
534531
t.Helper()
535532

536533
if err != nil {
537534
t.Fatalf("Failed to Do CRUD request: %s", err.Error())
538535
}
539536

540-
if resp == nil {
541-
t.Fatalf("Response is nil after Do CRUD request")
542-
}
543-
544-
if len(resp.Data) < expectedLen {
537+
if len(data) < expectedLen {
545538
t.Fatalf("Response Body len < %#v, actual len %#v",
546-
expectedLen, len(resp.Data))
539+
expectedLen, len(data))
547540
}
548541

549542
// resp.Data[0] - CRUD res.
550543
// resp.Data[1] - CRUD err.
551-
if expectedLen >= 2 && resp.Data[1] != nil {
552-
if crudErr, err := getCrudError(req, resp.Data[1]); err != nil {
544+
if expectedLen >= 2 && data[1] != nil {
545+
if crudErr, err := getCrudError(req, data[1]); err != nil {
553546
t.Fatalf("Failed to get CRUD error: %#v", err)
554547
} else if crudErr != nil {
555548
t.Fatalf("Failed to perform CRUD request on CRUD side: %#v", crudErr)
@@ -569,8 +562,8 @@ func TestCrudGenerateData(t *testing.T) {
569562
conn.Do(req).Get()
570563
}
571564

572-
resp, err := conn.Do(testCase.req).Get()
573-
testCrudRequestCheck(t, testCase.req, resp,
565+
data, err := conn.Do(testCase.req).Get()
566+
testCrudRequestCheck(t, testCase.req, data,
574567
err, testCase.expectedRespLen)
575568

576569
testSelectGeneratedData(t, conn, testCase.expectedTuplesCount)
@@ -591,8 +584,8 @@ func TestCrudProcessData(t *testing.T) {
591584
for _, testCase := range testProcessDataCases {
592585
t.Run(testCase.name, func(t *testing.T) {
593586
testCrudRequestPrepareData(t, conn)
594-
resp, err := conn.Do(testCase.req).Get()
595-
testCrudRequestCheck(t, testCase.req, resp,
587+
data, err := conn.Do(testCase.req).Get()
588+
testCrudRequestCheck(t, testCase.req, data,
596589
err, testCase.expectedRespLen)
597590
for i := 1010; i < 1020; i++ {
598591
req := tarantool.NewDeleteRequest(spaceName).
@@ -623,8 +616,8 @@ func TestCrudUpdateSplice(t *testing.T) {
623616
Opts(simpleOperationOpts)
624617

625618
testCrudRequestPrepareData(t, conn)
626-
resp, err := conn.Do(req).Get()
627-
testCrudRequestCheck(t, req, resp,
619+
data, err := conn.Do(req).Get()
620+
testCrudRequestCheck(t, req, data,
628621
err, 2)
629622
}
630623

@@ -648,8 +641,8 @@ func TestCrudUpsertSplice(t *testing.T) {
648641
Opts(simpleOperationOpts)
649642

650643
testCrudRequestPrepareData(t, conn)
651-
resp, err := conn.Do(req).Get()
652-
testCrudRequestCheck(t, req, resp,
644+
data, err := conn.Do(req).Get()
645+
testCrudRequestCheck(t, req, data,
653646
err, 2)
654647
}
655648

@@ -673,8 +666,8 @@ func TestCrudUpsertObjectSplice(t *testing.T) {
673666
Opts(simpleOperationOpts)
674667

675668
testCrudRequestPrepareData(t, conn)
676-
resp, err := conn.Do(req).Get()
677-
testCrudRequestCheck(t, req, resp,
669+
data, err := conn.Do(req).Get()
670+
testCrudRequestCheck(t, req, data,
678671
err, 2)
679672
}
680673

@@ -719,11 +712,11 @@ func TestUnflattenRows(t *testing.T) {
719712
req := crud.MakeReplaceRequest(spaceName).
720713
Tuple(tuple).
721714
Opts(simpleOperationOpts)
722-
resp, err := conn.Do(req).Get()
723-
testCrudRequestCheck(t, req, resp, err, 2)
715+
data, err := conn.Do(req).Get()
716+
testCrudRequestCheck(t, req, data, err, 2)
724717

725-
if res, ok = resp.Data[0].(map[interface{}]interface{}); !ok {
726-
t.Fatalf("Unexpected CRUD result: %#v", resp.Data[0])
718+
if res, ok = data[0].(map[interface{}]interface{}); !ok {
719+
t.Fatalf("Unexpected CRUD result: %#v", data[0])
727720
}
728721

729722
if rawMetadata, ok := res["metadata"]; !ok {
@@ -1293,21 +1286,21 @@ func TestNoreturnOption(t *testing.T) {
12931286
conn.Do(req).Get()
12941287
}
12951288

1296-
resp, err := conn.Do(testCase.req).Get()
1289+
data, err := conn.Do(testCase.req).Get()
12971290
if err != nil {
12981291
t.Fatalf("Failed to Do CRUD request: %s", err)
12991292
}
13001293

1301-
if len(resp.Data) == 0 {
1294+
if len(data) == 0 {
13021295
t.Fatalf("Expected explicit nil")
13031296
}
13041297

1305-
if resp.Data[0] != nil {
1306-
t.Fatalf("Expected nil result, got %v", resp.Data[0])
1298+
if data[0] != nil {
1299+
t.Fatalf("Expected nil result, got %v", data[0])
13071300
}
13081301

1309-
if len(resp.Data) >= 2 && resp.Data[1] != nil {
1310-
t.Fatalf("Expected no returned errors, got %v", resp.Data[1])
1302+
if len(data) >= 2 && data[1] != nil {
1303+
t.Fatalf("Expected no returned errors, got %v", data[1])
13111304
}
13121305

13131306
for i := 1010; i < 1020; i++ {

0 commit comments

Comments
 (0)