From: Serge Petrenko via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>,
tarantool-patches@dev.tarantool.org, vdavydov@tarantool.org
Subject: Re: [Tarantool-patches] [PATCH 2/9] error: introduce error_payload
Date: Fri, 12 Nov 2021 09:29:45 +0300 [thread overview]
Message-ID: <c1d70226-3348-65eb-6c15-0612ef47c603@tarantool.org> (raw)
In-Reply-To: <4dbb6e33-104e-67b5-8c8f-7b32a443d8be@tarantool.org>
12.11.2021 02:50, Vladislav Shpilevoy пишет:
> Hi! Thanks for the review!
>
> Could you please cut the diff not participating in the review when send
> next comments? It would greatly help to locate them.
Sure. Sorry for the inconvenience.
>
>>> diff --git a/src/lib/core/error_payload.c b/src/lib/core/error_payload.c
>>> new file mode 100644
>>> index 000000000..98ef08ada
>>> --- /dev/null
>>> +++ b/src/lib/core/error_payload.c
>>> @@ -0,0 +1,282 @@
> <...>
>
>>> +const char *
>>> +error_payload_get_str(const struct error_payload *e, const char *name)
>>> +{
>>> + const struct error_field *f = error_payload_find(e, name);
>>> + if (f == NULL)
>>> + return NULL;
>>> + const char *data = f->data;
>>> + if (mp_typeof(*data) != MP_STR)
>>> + return NULL;
>>> + uint32_t len;
>>> + /*
>>> + * 0 is explicitly written after encoded string to be able to return
>>> + * them without copying.
>>> + */
>>> + data = mp_decode_str(&data, &len);
>>> + assert(data[len] == 0);
>> 1. Nit: `data[len] == '\0'`. Here and everywhere else. This is up to you,
>> I'm just more used to '\0'.
> I like plain 0 more because it is a bit shorter and is highlighted in
> an editor as a number, which makes it stand out from regular characters.
Ok
>
>>> + return data;
>>> +}
>>> +
>>> +void
>>> +error_payload_set_str(struct error_payload *e, const char *name,
>>> + const char *value)
>>> +{
>>> + uint32_t len = strlen(value);
>>> + char *data = error_payload_prepare(
>>> + e, name, mp_sizeof_str(len), 1)->data;
>>> + /*
>>> + * 1 extra byte in the end is reserved to append 0 after the encoded
>>> + * string. To be able to return it from get() without copying.
>>> + */
>> 2. This comment is almost the same as the one in payload_get_str().
>> I propose to leave only one of them. Preferably the one in set_str().
> Ok, dropped from get_str():
>
> ====================
> @@ -34,10 +34,6 @@ error_payload_get_str(const struct error_payload *e, const char *name)
> if (mp_typeof(*data) != MP_STR)
> return NULL;
> uint32_t len;
> - /*
> - * 0 is explicitly written after encoded string to be able to return
> - * them without copying.
> - */
> ====================
>
>> diff --git a/src/lib/core/error_payload.c b/src/lib/core/error_payload.c
>> index 98ef08ada..cfa30919e 100644
>> --- a/src/lib/core/error_payload.c
>> +++ b/src/lib/core/error_payload.c
>> @@ -62,17 +62,14 @@ error_payload_get_uint(const struct error_payload *e, const char *name,
>> uint64_t *value)
>> {
>> const struct error_field *f = error_payload_find(e, name);
>> + *value = 0;
>> if (f == NULL)
>> - goto not_found;
>> + return false;
>> const char *data = f->data;
>> if (mp_typeof(*data) != MP_UINT)
>> - goto not_found;
>> + return false;
>> *value = mp_decode_uint(&data);
>> return true;
>> -
>> -not_found:
>> - *value = 0;
>> - return false;
>> }
>>
>> void
> I would apply this diff if not tt_uuid field type - I would
> need to make it the same to be consistent. While extra assignment
> of an 8-byte number probably can't be noticed on the success path,
> nil uuid copying could be something.
>
> Let me know if you still want that applied after this reasoning
> and I will do.
I see, never mind.
>
>>> +bool
>>> +error_payload_get_double(const struct error_payload *e, const char *name,
>>> + double *value)
>>> +{
>>> + const struct error_field *f = error_payload_find(e, name);
>>> + if (f == NULL)
>>> + goto not_found;
>>> + const char *data = f->data;
>>> + if (mp_typeof(*data) == MP_DOUBLE) {
>>> + *value = mp_decode_double(&data);
>>> + return true;
>>> + } else if (mp_typeof(*data) == MP_FLOAT) {
>>> + *value = mp_decode_float(&data);
>>> + return true;
>>> + }
>> 4. Why do you check for both MP_DOUBLE and MP_FLOAT here?
>> You only encode MP_DOUBLE.
> Because the fields could arrive from network from a connector,
> for instance. Connectors could encode floats. So I wanted this
> code be ready to that. Btw, I realized I didn't have tests for
> that. Added now:
>
> ====================
> @@ -181,7 +181,7 @@ static void
> test_payload_field_double(void)
> {
> header();
> - plan(13);
> + plan(14);
>
> struct error_payload p;
> error_payload_create(&p);
> @@ -216,6 +216,12 @@ test_payload_field_double(void)
> ok(!error_payload_get_double(&p, "key2", &val) && val == 0,
> "wrong type");
>
> + char buffer[16];
> + char *data = mp_encode_float(buffer, 0.5);
> + error_payload_set_mp(&p, "key2", buffer, data - buffer);
> + ok(error_payload_get_double(&p, "key2", &val) && val == 0.5,
> + "float 0.5");
> +
> error_payload_destroy(&p);
> ====================
>
>> I think we might have set_float() and get_float() one day, but looks
>> like they're not needed now.
> I added them in a first version, but then faced an issue what to
> do in get_float() when you see MP_DOUBLE? It appeared to be quite
> complicated to determine when a double could be truncated to float
> safely, so I decided not to do float get/set support at all. Only
> handle it in scope of getting a double.
>
>> get_float() would only accept MP_FLOAT then, and get_double() should
>> only accept MP_DOUBLE.
> The reasoning here is more or less similar to why I didn't add
> separate get/set_uint32 and only added uint64 called 'uint' - I
> didn't want the caller to care what was the subtype.
>
> I also thought about dropping both double and float support but
> then realized we use double for time and it is likely we will want
> to add timestamps/timeouts/durations to some errors eventually.
Thanks for the explanation!
> <...>
>
>>> +void
>>> +error_payload_set_mp(struct error_payload *e, const char *name,
>>> + const char *src, uint32_t size)
>>> +{
>>> + char *data;
>>> + if (mp_typeof(*src) == MP_STR) {
>>> + data = error_payload_prepare(e, name, size, 1)->data;
>>> + /*
>>> + * Add the terminating zero after the buffer so as get_str()
>>> + * would work without copying.
>>> + */
>> 5. Maybe shorten this comment to "\sa error_payload_set_str()" ?
> Done.
>
> ====================
> data = error_payload_prepare(e, name, size, 1)->data;
> - /*
> - * Add the terminating zero after the buffer so as get_str()
> - * would work without copying.
> - */
> + /* @sa error_payload_set_str(). */
> data[size] = 0;
> ====================
>
>>> diff --git a/src/lib/uuid/mp_uuid.c b/src/lib/uuid/mp_uuid.c
>>> index b2341ae36..a60716eb5 100644
>>> --- a/src/lib/uuid/mp_uuid.c
>>> +++ b/src/lib/uuid/mp_uuid.c
>>> @@ -113,3 +114,28 @@ mp_fprint_uuid(FILE *file, const char **data, uint32_t len)
>>> return -1;
>>> return fprintf(file, "%s", tt_uuid_str(&uuid));
>>> }
>>> +
>>> +bool
>>> +error_payload_get_uuid(const struct error_payload *e, const char *name,
>>> + struct tt_uuid *uuid)
>>> +{
>>> + const struct error_field *f = error_payload_find(e, name);
>>> + if (f == NULL)
>>> + goto not_found;
>>> + const char *data = f->data;
>>> + if (mp_decode_uuid(&data, uuid) == NULL)
>>> + goto not_found;
>>> + return true;
>>> +
>>> +not_found:
>>> + *uuid = uuid_nil;
>>> + return false;
>>> +}
>>> +
>> 6. I propose to get rid of the label here and set uuid to nil unconditionally.
>>
>> Would it be too expensive to do 2 struct assignments instead of one?
>> (uuid = uuid_nil; uuid = decoded_value).
> Answered in the previous comment about gotos.
--
Serge Petrenko
next prev parent reply other threads:[~2021-11-12 6:29 UTC|newest]
Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-11-05 23:56 [Tarantool-patches] [PATCH 0/9] ER_READONLY reason Vladislav Shpilevoy via Tarantool-patches
2021-11-05 23:56 ` [Tarantool-patches] [PATCH 1/9] diag: return created error from diag_set() Vladislav Shpilevoy via Tarantool-patches
2021-11-05 23:56 ` [Tarantool-patches] [PATCH 2/9] error: introduce error_payload Vladislav Shpilevoy via Tarantool-patches
2021-11-08 15:14 ` Serge Petrenko via Tarantool-patches
2021-11-11 23:50 ` Vladislav Shpilevoy via Tarantool-patches
2021-11-12 6:29 ` Serge Petrenko via Tarantool-patches [this message]
2021-11-05 23:56 ` [Tarantool-patches] [PATCH 3/9] error: move code to struct error from ClientError Vladislav Shpilevoy via Tarantool-patches
2021-11-08 15:15 ` Serge Petrenko via Tarantool-patches
2021-11-11 23:50 ` Vladislav Shpilevoy via Tarantool-patches
2021-11-12 6:31 ` Serge Petrenko via Tarantool-patches
2021-11-05 23:56 ` [Tarantool-patches] [PATCH 4/9] error: use error_payload to store optional members Vladislav Shpilevoy via Tarantool-patches
2021-11-05 23:56 ` [Tarantool-patches] [PATCH 5/9] error: use error_payload in MessagePack codecs Vladislav Shpilevoy via Tarantool-patches
2021-11-05 23:56 ` [Tarantool-patches] [PATCH 6/9] error: use error_payload in Lua Vladislav Shpilevoy via Tarantool-patches
2021-11-05 23:56 ` [Tarantool-patches] [PATCH 7/9] luatest: copy config in cluster:build_server() Vladislav Shpilevoy via Tarantool-patches
2021-11-05 23:56 ` [Tarantool-patches] [PATCH 8/9] luatest: add new helpers for 'server' object Vladislav Shpilevoy via Tarantool-patches
2021-11-08 15:16 ` Serge Petrenko via Tarantool-patches
2021-11-11 23:51 ` Vladislav Shpilevoy via Tarantool-patches
2021-11-05 23:56 ` [Tarantool-patches] [PATCH 9/9] box: enrich ER_READONLY with new details Vladislav Shpilevoy via Tarantool-patches
2021-11-06 19:30 ` Cyrill Gorcunov via Tarantool-patches
2021-11-07 16:45 ` Vladislav Shpilevoy via Tarantool-patches
2021-11-07 20:19 ` Cyrill Gorcunov via Tarantool-patches
2021-11-08 15:18 ` Serge Petrenko via Tarantool-patches
2021-11-11 23:52 ` Vladislav Shpilevoy via Tarantool-patches
2021-11-08 14:25 ` [Tarantool-patches] [PATCH 0/9] ER_READONLY reason Vladimir Davydov via Tarantool-patches
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=c1d70226-3348-65eb-6c15-0612ef47c603@tarantool.org \
--to=tarantool-patches@dev.tarantool.org \
--cc=sergepetrenko@tarantool.org \
--cc=v.shpilevoy@tarantool.org \
--cc=vdavydov@tarantool.org \
--subject='Re: [Tarantool-patches] [PATCH 2/9] error: introduce error_payload' \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox