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