Skip to content

Commit

Permalink
code-health: update format for Call to 1.7
Browse files Browse the repository at this point in the history
An incompatible change was introduced in
Tarantool 1.7 which was released in 2016.
This change is about a new binary protocol
command for CALL, which no more restricts
a function to returning an array of tuples
and allows returning an arbitrary MsgPack/JSON
result, including scalars, nil and void (nothing).

We should be in-line with tarantool here and
provide `Call17` as just `Call` and rename
current `Call` to `Call16`.

Closes #125
  • Loading branch information
AnaNek committed Apr 25, 2022
1 parent cb9f156 commit a82f715
Show file tree
Hide file tree
Showing 11 changed files with 70 additions and 72 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.

### Changed

- Breaking change: rename `Call` to `Call16` and `Call17` to `Call` (#125)
- Handle everything with `go test` (#115)
- Use plain package instead of module for UUID submodule (#134)
- Reset buffer if its average use size smaller than quater of capacity (#95)
Expand Down
4 changes: 2 additions & 2 deletions connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ func (d defaultLogger) Report(event ConnLogKind, conn *Connection, v ...interfac
//
// ATTENTION: result argument for *Typed methods should deserialize from
// msgpack array, cause Tarantool always returns result as an array.
// For all space related methods and Call* (but not Call17*) methods Tarantool
// For all space related methods and Call16* (but not Call*) methods Tarantool
// always returns array of array (array of tuples for space related methods).
// For Eval* and Call17* Tarantool always returns array, but does not forces
// For Eval* and Call* Tarantool always returns array, but does not forces
// array of arrays.
type Connection struct {
addr string
Expand Down
6 changes: 3 additions & 3 deletions connector.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ type Connector interface {
Delete(space, index interface{}, key interface{}) (resp *Response, err error)
Update(space, index interface{}, key, ops interface{}) (resp *Response, err error)
Upsert(space interface{}, tuple, ops interface{}) (resp *Response, err error)
Call16(functionName string, args interface{}) (resp *Response, err error)
Call(functionName string, args interface{}) (resp *Response, err error)
Call17(functionName string, args interface{}) (resp *Response, err error)
Eval(expr string, args interface{}) (resp *Response, err error)

GetTyped(space, index interface{}, key interface{}, result interface{}) (err error)
Expand All @@ -24,8 +24,8 @@ type Connector interface {
ReplaceTyped(space interface{}, tuple interface{}, result interface{}) (err error)
DeleteTyped(space, index interface{}, key interface{}, result interface{}) (err error)
UpdateTyped(space, index interface{}, key, ops interface{}, result interface{}) (err error)
Call16Typed(functionName string, args interface{}, result interface{}) (err error)
CallTyped(functionName string, args interface{}, result interface{}) (err error)
Call17Typed(functionName string, args interface{}, result interface{}) (err error)
EvalTyped(expr string, args interface{}, result interface{}) (err error)

SelectAsync(space, index interface{}, offset, limit, iterator uint32, key interface{}) *Future
Expand All @@ -34,7 +34,7 @@ type Connector interface {
DeleteAsync(space, index interface{}, key interface{}) *Future
UpdateAsync(space, index interface{}, key, ops interface{}) *Future
UpsertAsync(space interface{}, tuple interface{}, ops interface{}) *Future
Call16Async(functionName string, args interface{}) *Future
CallAsync(functionName string, args interface{}) *Future
Call17Async(functionName string, args interface{}) *Future
EvalAsync(expr string, args interface{}) *Future
}
4 changes: 2 additions & 2 deletions const.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ const (
ReplaceRequest = 3
UpdateRequest = 4
DeleteRequest = 5
CallRequest = 6 /* call in 1.6 format */
Call16Request = 6 /* call in 1.6 format */
AuthRequest = 7
EvalRequest = 8
UpsertRequest = 9
Call17Request = 10
CallRequest = 10 /* call in >=1.7 format */
PingRequest = 64
SubscribeRequest = 66

Expand Down
4 changes: 2 additions & 2 deletions example_custom_unpacking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func Example_customUnpacking() {
fmt.Println("Tuples (tuples2):", tuples2)

// Call a function "func_name" returning a table of custom tuples.
var tuples3 []Tuple3
var tuples3 [][]Tuple3
err = conn.CallTyped("func_name", []interface{}{}, &tuples3)
if err != nil {
log.Fatalf("Failed to CallTyped: %s", err.Error())
Expand All @@ -130,6 +130,6 @@ func Example_customUnpacking() {
// Code 0
// Tuples (tuples1) [{777 orig [{lol 1} {wut 3}]}]
// Tuples (tuples2): [{{} 777 orig [{lol 1} {wut 3}]}]
// Tuples (tuples3): [{{} 221 [{Moscow 34} {Minsk 23} {Kiev 31}]}]
// Tuples (tuples3): [[{{} 221 [{Moscow 34} {Minsk 23} {Kiev 31}]}]]

}
4 changes: 2 additions & 2 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,12 @@ func ExampleConnection_Update() {
// Data [[14 bye bla]]
}

func ExampleConnection_Call17() {
func ExampleConnection_Call() {
conn := example_connect()
defer conn.Close()

// Call a function 'simple_incr' with arguments.
resp, err := conn.Call17("simple_incr", []interface{}{1})
resp, err := conn.Call("simple_incr", []interface{}{1})
fmt.Println("Call simple_incr()")
fmt.Println("Error", err)
fmt.Println("Code", resp.Code)
Expand Down
44 changes: 22 additions & 22 deletions multi/multi.go
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ func (connMulti *ConnectionMulti) checker() {
continue
}
var resp [][]string
err := connMulti.Call17Typed(connMulti.opts.NodesGetFunctionName, []interface{}{}, &resp)
err := connMulti.CallTyped(connMulti.opts.NodesGetFunctionName, []interface{}{}, &resp)
if err != nil {
continue
}
Expand Down Expand Up @@ -321,18 +321,18 @@ func (connMulti *ConnectionMulti) Upsert(space interface{}, tuple, ops interface
return connMulti.getCurrentConnection().Upsert(space, tuple, ops)
}

// Call calls registered Tarantool function.
// Call16 calls registered Tarantool function.
// It uses request code for Tarantool 1.6, so result is converted to array of
// arrays.
func (connMulti *ConnectionMulti) Call(functionName string, args interface{}) (resp *tarantool.Response, err error) {
return connMulti.getCurrentConnection().Call(functionName, args)
func (connMulti *ConnectionMulti) Call16(functionName string, args interface{}) (resp *tarantool.Response, err error) {
return connMulti.getCurrentConnection().Call16(functionName, args)
}

// Call17 calls registered Tarantool function.
// It uses request code for Tarantool 1.7, so result is not converted
// Call calls registered Tarantool function.
// It uses request code for Tarantool >=1.7, so result is not converted
// (though, keep in mind, result is always array).
func (connMulti *ConnectionMulti) Call17(functionName string, args interface{}) (resp *tarantool.Response, err error) {
return connMulti.getCurrentConnection().Call17(functionName, args)
func (connMulti *ConnectionMulti) Call(functionName string, args interface{}) (resp *tarantool.Response, err error) {
return connMulti.getCurrentConnection().Call(functionName, args)
}

// Eval passes Lua expression for evaluation.
Expand Down Expand Up @@ -375,18 +375,18 @@ func (connMulti *ConnectionMulti) UpdateTyped(space, index interface{}, key, ops
return connMulti.getCurrentConnection().UpdateTyped(space, index, key, ops, result)
}

// CallTyped calls registered function.
// Call16Typed calls registered function.
// It uses request code for Tarantool 1.6, so result is converted to array of
// arrays.
func (connMulti *ConnectionMulti) CallTyped(functionName string, args interface{}, result interface{}) (err error) {
return connMulti.getCurrentConnection().CallTyped(functionName, args, result)
func (connMulti *ConnectionMulti) Call16Typed(functionName string, args interface{}, result interface{}) (err error) {
return connMulti.getCurrentConnection().Call16Typed(functionName, args, result)
}

// Call17Typed calls registered function.
// It uses request code for Tarantool 1.7, so result is not converted (though,
// CallTyped calls registered function.
// It uses request code for Tarantool >=1.7, so result is not converted (though,
// keep in mind, result is always array)
func (connMulti *ConnectionMulti) Call17Typed(functionName string, args interface{}, result interface{}) (err error) {
return connMulti.getCurrentConnection().Call17Typed(functionName, args, result)
func (connMulti *ConnectionMulti) CallTyped(functionName string, args interface{}, result interface{}) (err error) {
return connMulti.getCurrentConnection().CallTyped(functionName, args, result)
}

// EvalTyped passes Lua expression for evaluation.
Expand Down Expand Up @@ -429,18 +429,18 @@ func (connMulti *ConnectionMulti) UpsertAsync(space interface{}, tuple interface
return connMulti.getCurrentConnection().UpsertAsync(space, tuple, ops)
}

// CallAsync sends a call to registered Tarantool function and returns Future.
// Call16Async sends a call to registered Tarantool function and returns Future.
// It uses request code for Tarantool 1.6, so future's result is always array
// of arrays.
func (connMulti *ConnectionMulti) CallAsync(functionName string, args interface{}) *tarantool.Future {
return connMulti.getCurrentConnection().CallAsync(functionName, args)
func (connMulti *ConnectionMulti) Call16Async(functionName string, args interface{}) *tarantool.Future {
return connMulti.getCurrentConnection().Call16Async(functionName, args)
}

// Call17Async sends a call to registered Tarantool function and returns Future.
// It uses request code for Tarantool 1.7, so future's result will not be converted
// CallAsync sends a call to registered Tarantool function and returns Future.
// It uses request code for Tarantool >=1.7, so future's result will not be converted
// (though, keep in mind, result is always array).
func (connMulti *ConnectionMulti) Call17Async(functionName string, args interface{}) *tarantool.Future {
return connMulti.getCurrentConnection().Call17Async(functionName, args)
func (connMulti *ConnectionMulti) CallAsync(functionName string, args interface{}) *tarantool.Future {
return connMulti.getCurrentConnection().CallAsync(functionName, args)
}

// EvalAsync passes Lua expression for evaluation.
Expand Down
7 changes: 2 additions & 5 deletions queue/queue.go
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ func (q *queue) Kick(count uint64) (uint64, error) {
resp, err := q.conn.Call(q.cmds.kick, []interface{}{count})
var id uint64
if err == nil {
id = resp.Data[0].([]interface{})[0].(uint64)
id = resp.Data[0].(uint64)
}
return id, err
}
Expand All @@ -309,10 +309,7 @@ func (q *queue) Statistic() (interface{}, error) {
}

if len(resp.Data) != 0 {
data, ok := resp.Data[0].([]interface{})
if ok && len(data) != 0 {
return data[0], nil
}
return resp.Data[0], nil
}

return nil, nil
Expand Down
52 changes: 26 additions & 26 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,21 +96,21 @@ func (conn *Connection) Upsert(space interface{}, tuple, ops interface{}) (resp
return conn.UpsertAsync(space, tuple, ops).Get()
}

// Call calls registered Tarantool function.
// Call16 calls registered Tarantool function.
// It uses request code for Tarantool 1.6, so result is converted to array of arrays
//
// It is equal to conn.CallAsync(functionName, args).Get().
func (conn *Connection) Call(functionName string, args interface{}) (resp *Response, err error) {
return conn.CallAsync(functionName, args).Get()
// It is equal to conn.Call16Async(functionName, args).Get().
func (conn *Connection) Call16(functionName string, args interface{}) (resp *Response, err error) {
return conn.Call16Async(functionName, args).Get()
}

// Call17 calls registered Tarantool function.
// It uses request code for Tarantool 1.7, so result is not converted
// Call calls registered Tarantool function.
// It uses request code for Tarantool >=1.7, so result is not converted
// (though, keep in mind, result is always array)
//
// It is equal to conn.Call17Async(functionName, args).Get().
func (conn *Connection) Call17(functionName string, args interface{}) (resp *Response, err error) {
return conn.Call17Async(functionName, args).Get()
// It is equal to conn.CallAsync(functionName, args).Get().
func (conn *Connection) Call(functionName string, args interface{}) (resp *Response, err error) {
return conn.CallAsync(functionName, args).Get()
}

// Eval passes Lua expression for evaluation.
Expand Down Expand Up @@ -188,21 +188,21 @@ func (conn *Connection) UpdateTyped(space, index interface{}, key, ops interface
return conn.UpdateAsync(space, index, key, ops).GetTyped(result)
}

// CallTyped calls registered function.
// Call16Typed calls registered function.
// It uses request code for Tarantool 1.6, so result is converted to array of arrays
//
// It is equal to conn.CallAsync(functionName, args).GetTyped(&result).
func (conn *Connection) CallTyped(functionName string, args interface{}, result interface{}) (err error) {
return conn.CallAsync(functionName, args).GetTyped(result)
// It is equal to conn.Call16Async(functionName, args).GetTyped(&result).
func (conn *Connection) Call16Typed(functionName string, args interface{}, result interface{}) (err error) {
return conn.Call16Async(functionName, args).GetTyped(result)
}

// Call17Typed calls registered function.
// It uses request code for Tarantool 1.7, so result is not converted
// CallTyped calls registered function.
// It uses request code for Tarantool >=1.7, so result is not converted
// (though, keep in mind, result is always array)
//
// It is equal to conn.Call17Async(functionName, args).GetTyped(&result).
func (conn *Connection) Call17Typed(functionName string, args interface{}, result interface{}) (err error) {
return conn.Call17Async(functionName, args).GetTyped(result)
// It is equal to conn.CallAsync(functionName, args).GetTyped(&result).
func (conn *Connection) CallTyped(functionName string, args interface{}, result interface{}) (err error) {
return conn.CallAsync(functionName, args).GetTyped(result)
}

// EvalTyped passes Lua expression for evaluation.
Expand Down Expand Up @@ -307,10 +307,10 @@ func (conn *Connection) UpsertAsync(space interface{}, tuple interface{}, ops in
})
}

// CallAsync sends a call to registered Tarantool function and returns Future.
// Call16Async sends a call to registered Tarantool function and returns Future.
// It uses request code for Tarantool 1.6, so future's result is always array of arrays
func (conn *Connection) CallAsync(functionName string, args interface{}) *Future {
future := conn.newFuture(CallRequest)
func (conn *Connection) Call16Async(functionName string, args interface{}) *Future {
future := conn.newFuture(Call16Request)
return future.send(conn, func(enc *msgpack.Encoder) error {
enc.EncodeMapLen(2)
enc.EncodeUint64(KeyFunctionName)
Expand All @@ -320,11 +320,11 @@ func (conn *Connection) CallAsync(functionName string, args interface{}) *Future
})
}

// Call17Async sends a call to registered Tarantool function and returns Future.
// It uses request code for Tarantool 1.7, so future's result will not be converted
// CallAsync sends a call to registered Tarantool function and returns Future.
// It uses request code for Tarantool >=1.7, so future's result will not be converted
// (though, keep in mind, result is always array)
func (conn *Connection) Call17Async(functionName string, args interface{}) *Future {
future := conn.newFuture(Call17Request)
func (conn *Connection) CallAsync(functionName string, args interface{}) *Future {
future := conn.newFuture(CallRequest)
return future.send(conn, func(enc *msgpack.Encoder) error {
enc.EncodeMapLen(2)
enc.EncodeUint64(KeyFunctionName)
Expand Down Expand Up @@ -426,7 +426,7 @@ func (fut *Future) Get() (*Response, error) {
// GetTyped waits for Future and calls msgpack.Decoder.Decode(result) if no error happens.
// It is could be much faster than Get() function.
//
// Note: Tarantool usually returns array of tuples (except for Eval and Call17 actions)
// Note: Tarantool usually returns array of tuples (except for Eval and Call actions)
func (fut *Future) GetTyped(result interface{}) error {
fut.wait()
if fut.err != nil {
Expand Down
2 changes: 1 addition & 1 deletion response.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ func (resp *Response) String() (str string) {
return fmt.Sprintf("<%d ERR 0x%x %s>", resp.RequestId, resp.Code, resp.Error)
}

// Tuples converts result of Eval and Call17 to same format
// Tuples converts result of Eval and Call to same format
// as other actions returns (i.e. array of arrays).
func (resp *Response) Tuples() (res [][]interface{}) {
res = make([][]interface{}, len(resp.Data))
Expand Down
14 changes: 7 additions & 7 deletions tarantool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -620,25 +620,25 @@ func TestClient(t *testing.T) {
t.Errorf("Result len of SelectTyped != 1")
}

// Call
resp, err = conn.Call("box.info", []interface{}{"box.schema.SPACE_ID"})
// Call16
resp, err = conn.Call16("box.info", []interface{}{"box.schema.SPACE_ID"})
if err != nil {
t.Errorf("Failed to Call: %s", err.Error())
t.Errorf("Failed to Call16: %s", err.Error())
}
if resp == nil {
t.Errorf("Response is nil after Call")
t.Errorf("Response is nil after Call16")
}
if len(resp.Data) < 1 {
t.Errorf("Response.Data is empty after Eval")
}

// Call vs Call17
resp, err = conn.Call("simple_incr", []interface{}{1})
// Call16 vs Call
resp, err = conn.Call16("simple_incr", []interface{}{1})
if resp.Data[0].([]interface{})[0].(uint64) != 2 {
t.Errorf("result is not {{1}} : %v", resp.Data)
}

resp, err = conn.Call17("simple_incr", []interface{}{1})
resp, err = conn.Call("simple_incr", []interface{}{1})
if resp.Data[0].(uint64) != 2 {
t.Errorf("result is not {{1}} : %v", resp.Data)
}
Expand Down

0 comments on commit a82f715

Please sign in to comment.