diff --git a/CHANGELOG.md b/CHANGELOG.md index 020a37c70..1fc71aac7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release. - Meaningful description for read/write socket errors (#129) - Support password and password file to decrypt private SSL key file (#319) - Support `operation_data` in `crud.Error` (#330) +- Support `fetch_latest_metadata` option for crud requests with metadata (#335) ### Changed diff --git a/crud/get.go b/crud/get.go index a957219dc..fcfef5426 100644 --- a/crud/get.go +++ b/crud/get.go @@ -29,15 +29,20 @@ type GetOpts struct { // Balance is a parameter to use replica according to vshard // load balancing policy. Balance OptBool + // FetchLatestMetadata guarantees the up-to-date metadata (space format) + // in first return value, otherwise it may not take into account + // the latest migration of the data format. Performance overhead is up to 15%. + // Disabled by default. + FetchLatestMetadata OptBool } // EncodeMsgpack provides custom msgpack encoder. func (opts GetOpts) EncodeMsgpack(enc *msgpack.Encoder) error { - const optsCnt = 7 + const optsCnt = 8 names := [optsCnt]string{timeoutOptName, vshardRouterOptName, fieldsOptName, bucketIdOptName, modeOptName, - preferReplicaOptName, balanceOptName} + preferReplicaOptName, balanceOptName, fetchLatestMetadataOptName} values := [optsCnt]interface{}{} exists := [optsCnt]bool{} values[0], exists[0] = opts.Timeout.Get() @@ -47,6 +52,7 @@ func (opts GetOpts) EncodeMsgpack(enc *msgpack.Encoder) error { values[4], exists[4] = opts.Mode.Get() values[5], exists[5] = opts.PreferReplica.Get() values[6], exists[6] = opts.Balance.Get() + values[7], exists[7] = opts.FetchLatestMetadata.Get() return encodeOptions(enc, names[:], values[:], exists[:]) } diff --git a/crud/options.go b/crud/options.go index f9cde7be8..aab4dcbaf 100644 --- a/crud/options.go +++ b/crud/options.go @@ -21,6 +21,7 @@ const ( firstOptName = "first" afterOptName = "after" batchSizeOptName = "batch_size" + fetchLatestMetadataOptName = "fetch_latest_metadata" ) // OptUint is an optional uint. @@ -150,20 +151,26 @@ type SimpleOperationOpts struct { Fields OptTuple // BucketId is a bucket ID. BucketId OptUint + // FetchLatestMetadata guarantees the up-to-date metadata (space format) + // in first return value, otherwise it may not take into account + // the latest migration of the data format. Performance overhead is up to 15%. + // Disabled by default. + FetchLatestMetadata OptBool } // EncodeMsgpack provides custom msgpack encoder. func (opts SimpleOperationOpts) EncodeMsgpack(enc *msgpack.Encoder) error { - const optsCnt = 4 + const optsCnt = 5 names := [optsCnt]string{timeoutOptName, vshardRouterOptName, - fieldsOptName, bucketIdOptName} + fieldsOptName, bucketIdOptName, fetchLatestMetadataOptName} values := [optsCnt]interface{}{} exists := [optsCnt]bool{} values[0], exists[0] = opts.Timeout.Get() values[1], exists[1] = opts.VshardRouter.Get() values[2], exists[2] = opts.Fields.Get() values[3], exists[3] = opts.BucketId.Get() + values[4], exists[4] = opts.FetchLatestMetadata.Get() return encodeOptions(enc, names[:], values[:], exists[:]) } @@ -184,14 +191,20 @@ type SimpleOperationObjectOpts struct { // SkipNullabilityCheckOnFlatten is a parameter to allow // setting null values to non-nullable fields. SkipNullabilityCheckOnFlatten OptBool + // FetchLatestMetadata guarantees the up-to-date metadata (space format) + // in first return value, otherwise it may not take into account + // the latest migration of the data format. Performance overhead is up to 15%. + // Disabled by default. + FetchLatestMetadata OptBool } // EncodeMsgpack provides custom msgpack encoder. func (opts SimpleOperationObjectOpts) EncodeMsgpack(enc *msgpack.Encoder) error { - const optsCnt = 5 + const optsCnt = 6 names := [optsCnt]string{timeoutOptName, vshardRouterOptName, - fieldsOptName, bucketIdOptName, skipNullabilityCheckOnFlattenOptName} + fieldsOptName, bucketIdOptName, skipNullabilityCheckOnFlattenOptName, + fetchLatestMetadataOptName} values := [optsCnt]interface{}{} exists := [optsCnt]bool{} values[0], exists[0] = opts.Timeout.Get() @@ -199,6 +212,7 @@ func (opts SimpleOperationObjectOpts) EncodeMsgpack(enc *msgpack.Encoder) error values[2], exists[2] = opts.Fields.Get() values[3], exists[3] = opts.BucketId.Get() values[4], exists[4] = opts.SkipNullabilityCheckOnFlatten.Get() + values[5], exists[5] = opts.FetchLatestMetadata.Get() return encodeOptions(enc, names[:], values[:], exists[:]) } @@ -221,14 +235,20 @@ type OperationManyOpts struct { // RollbackOnError is a parameter because of what any failed operation // will lead to rollback on a storage, where the operation is failed. RollbackOnError OptBool + // FetchLatestMetadata guarantees the up-to-date metadata (space format) + // in first return value, otherwise it may not take into account + // the latest migration of the data format. Performance overhead is up to 15%. + // Disabled by default. + FetchLatestMetadata OptBool } // EncodeMsgpack provides custom msgpack encoder. func (opts OperationManyOpts) EncodeMsgpack(enc *msgpack.Encoder) error { - const optsCnt = 5 + const optsCnt = 6 names := [optsCnt]string{timeoutOptName, vshardRouterOptName, - fieldsOptName, stopOnErrorOptName, rollbackOnErrorOptName} + fieldsOptName, stopOnErrorOptName, rollbackOnErrorOptName, + fetchLatestMetadataOptName} values := [optsCnt]interface{}{} exists := [optsCnt]bool{} values[0], exists[0] = opts.Timeout.Get() @@ -236,6 +256,7 @@ func (opts OperationManyOpts) EncodeMsgpack(enc *msgpack.Encoder) error { values[2], exists[2] = opts.Fields.Get() values[3], exists[3] = opts.StopOnError.Get() values[4], exists[4] = opts.RollbackOnError.Get() + values[5], exists[5] = opts.FetchLatestMetadata.Get() return encodeOptions(enc, names[:], values[:], exists[:]) } @@ -261,11 +282,16 @@ type OperationObjectManyOpts struct { // SkipNullabilityCheckOnFlatten is a parameter to allow // setting null values to non-nullable fields. SkipNullabilityCheckOnFlatten OptBool + // FetchLatestMetadata guarantees the up-to-date metadata (space format) + // in first return value, otherwise it may not take into account + // the latest migration of the data format. Performance overhead is up to 15%. + // Disabled by default. + FetchLatestMetadata OptBool } // EncodeMsgpack provides custom msgpack encoder. func (opts OperationObjectManyOpts) EncodeMsgpack(enc *msgpack.Encoder) error { - const optsCnt = 6 + const optsCnt = 7 names := [optsCnt]string{timeoutOptName, vshardRouterOptName, fieldsOptName, stopOnErrorOptName, rollbackOnErrorOptName, @@ -278,6 +304,7 @@ func (opts OperationObjectManyOpts) EncodeMsgpack(enc *msgpack.Encoder) error { values[3], exists[3] = opts.StopOnError.Get() values[4], exists[4] = opts.RollbackOnError.Get() values[5], exists[5] = opts.SkipNullabilityCheckOnFlatten.Get() + values[6], exists[6] = opts.FetchLatestMetadata.Get() return encodeOptions(enc, names[:], values[:], exists[:]) } @@ -292,18 +319,25 @@ type BorderOpts struct { VshardRouter OptString // Fields is field names for getting only a subset of fields. Fields OptTuple + // FetchLatestMetadata guarantees the up-to-date metadata (space format) + // in first return value, otherwise it may not take into account + // the latest migration of the data format. Performance overhead is up to 15%. + // Disabled by default. + FetchLatestMetadata OptBool } // EncodeMsgpack provides custom msgpack encoder. func (opts BorderOpts) EncodeMsgpack(enc *msgpack.Encoder) error { - const optsCnt = 3 + const optsCnt = 4 - names := [optsCnt]string{timeoutOptName, vshardRouterOptName, fieldsOptName} + names := [optsCnt]string{timeoutOptName, vshardRouterOptName, fieldsOptName, + skipNullabilityCheckOnFlattenOptName} values := [optsCnt]interface{}{} exists := [optsCnt]bool{} values[0], exists[0] = opts.Timeout.Get() values[1], exists[1] = opts.VshardRouter.Get() values[2], exists[2] = opts.Fields.Get() + values[3], exists[3] = opts.FetchLatestMetadata.Get() return encodeOptions(enc, names[:], values[:], exists[:]) } diff --git a/crud/select.go b/crud/select.go index 073c9492b..0d0b5708a 100644 --- a/crud/select.go +++ b/crud/select.go @@ -41,17 +41,22 @@ type SelectOpts struct { // Fullscan describes if a critical log entry will be skipped on // potentially long select. Fullscan OptBool + // FetchLatestMetadata guarantees the up-to-date metadata (space format) + // in first return value, otherwise it may not take into account + // the latest migration of the data format. Performance overhead is up to 15%. + // Disabled by default. + FetchLatestMetadata OptBool } // EncodeMsgpack provides custom msgpack encoder. func (opts SelectOpts) EncodeMsgpack(enc *msgpack.Encoder) error { - const optsCnt = 12 + const optsCnt = 13 names := [optsCnt]string{timeoutOptName, vshardRouterOptName, fieldsOptName, bucketIdOptName, modeOptName, preferReplicaOptName, balanceOptName, firstOptName, afterOptName, batchSizeOptName, - forceMapCallOptName, fullscanOptName} + forceMapCallOptName, fullscanOptName, fetchLatestMetadataOptName} values := [optsCnt]interface{}{} exists := [optsCnt]bool{} values[0], exists[0] = opts.Timeout.Get() @@ -66,6 +71,7 @@ func (opts SelectOpts) EncodeMsgpack(enc *msgpack.Encoder) error { values[9], exists[9] = opts.BatchSize.Get() values[10], exists[10] = opts.ForceMapCall.Get() values[11], exists[11] = opts.Fullscan.Get() + values[12], exists[12] = opts.FetchLatestMetadata.Get() return encodeOptions(enc, names[:], values[:], exists[:]) } diff --git a/crud/tarantool_test.go b/crud/tarantool_test.go index 576d973e8..f02605fea 100644 --- a/crud/tarantool_test.go +++ b/crud/tarantool_test.go @@ -48,7 +48,8 @@ var operations = []crud.Operation{ } var selectOpts = crud.SelectOpts{ - Timeout: crud.MakeOptUint(timeout), + Timeout: crud.MakeOptUint(timeout), + FetchLatestMetadata: crud.MakeOptBool(true), } var countOpts = crud.CountOpts{ @@ -56,16 +57,19 @@ var countOpts = crud.CountOpts{ } var getOpts = crud.GetOpts{ - Timeout: crud.MakeOptUint(timeout), - Mode: crud.MakeOptString("read"), + Timeout: crud.MakeOptUint(timeout), + Mode: crud.MakeOptString("read"), + FetchLatestMetadata: crud.MakeOptBool(true), } var minOpts = crud.MinOpts{ - Timeout: crud.MakeOptUint(timeout), + Timeout: crud.MakeOptUint(timeout), + FetchLatestMetadata: crud.MakeOptBool(true), } var maxOpts = crud.MaxOpts{ - Timeout: crud.MakeOptUint(timeout), + Timeout: crud.MakeOptUint(timeout), + FetchLatestMetadata: crud.MakeOptBool(true), } var baseOpts = crud.BaseOpts{ @@ -73,19 +77,23 @@ var baseOpts = crud.BaseOpts{ } var simpleOperationOpts = crud.SimpleOperationOpts{ - Timeout: crud.MakeOptUint(timeout), + Timeout: crud.MakeOptUint(timeout), + FetchLatestMetadata: crud.MakeOptBool(true), } var simpleOperationObjectOpts = crud.SimpleOperationObjectOpts{ - Timeout: crud.MakeOptUint(timeout), + Timeout: crud.MakeOptUint(timeout), + FetchLatestMetadata: crud.MakeOptBool(true), } var opManyOpts = crud.OperationManyOpts{ - Timeout: crud.MakeOptUint(timeout), + Timeout: crud.MakeOptUint(timeout), + FetchLatestMetadata: crud.MakeOptBool(true), } var opObjManyOpts = crud.OperationObjectManyOpts{ - Timeout: crud.MakeOptUint(timeout), + Timeout: crud.MakeOptUint(timeout), + FetchLatestMetadata: crud.MakeOptBool(true), } var conditions = []crud.Condition{