diff --git a/src/box/iproto.cc b/src/box/iproto.cc index 17d2ecfed8a7b93ca50ec8df5ee23ea505ae239e..d16178f97a8381fbe474131c22821cfdcdaea466 100644 --- a/src/box/iproto.cc +++ b/src/box/iproto.cc @@ -301,16 +301,17 @@ iproto_connection_stop(struct iproto_connection *con) * closing. * @param sock Socket to write to. * @param error Error to write. + * @param sync Request sync. */ static inline void -iproto_write_error_blocking(int sock, const struct error *e) +iproto_write_error_blocking(int sock, const struct error *e, uint64_t sync) { /* Set to blocking to write the error. */ int flags = fcntl(sock, F_GETFL, 0); if (flags < 0) return; (void) fcntl(sock, F_SETFL, flags & (~O_NONBLOCK)); - iproto_write_error(sock, e, ::schema_version); + iproto_write_error(sock, e, ::schema_version, sync); (void) fcntl(sock, F_SETFL, flags); } @@ -826,7 +827,7 @@ iproto_connection_on_input(ev_loop *loop, struct ev_io *watcher, iproto_enqueue_batch(con, in); } catch (Exception *e) { /* Best effort at sending the error message to the client. */ - iproto_write_error_blocking(fd, e); + iproto_write_error_blocking(fd, e, 0); e->log(); iproto_connection_close(con); } @@ -1079,7 +1080,7 @@ tx_process_join_subscribe(struct cmsg *m) } catch (SocketError *e) { throw; /* don't write error response to prevent SIGPIPE */ } catch (Exception *e) { - iproto_write_error_blocking(con->input.fd, e); + iproto_write_error_blocking(con->input.fd, e, msg->header.sync); } } diff --git a/src/box/xrow.c b/src/box/xrow.c index 2adfc01efc1ed4fa401745f49c027671b578e458..eeb61582538350aa83b8d890a769511998520237 100644 --- a/src/box/xrow.c +++ b/src/box/xrow.c @@ -287,7 +287,8 @@ iproto_reply_error(struct obuf *out, const struct error *e, uint64_t sync, } void -iproto_write_error(int fd, const struct error *e, uint32_t schema_version) +iproto_write_error(int fd, const struct error *e, uint32_t schema_version, + uint64_t sync) { uint32_t msg_len = strlen(e->errmsg); uint32_t errcode = box_error_code(e); @@ -295,7 +296,7 @@ iproto_write_error(int fd, const struct error *e, uint32_t schema_version) char header[IPROTO_HEADER_LEN]; struct iproto_body_bin body = iproto_error_bin; - iproto_header_encode(header, iproto_encode_error(errcode), 0, + iproto_header_encode(header, iproto_encode_error(errcode), sync, schema_version, sizeof(body) + msg_len); body.v_data_len = mp_bswap_u32(msg_len); diff --git a/src/box/xrow.h b/src/box/xrow.h index ab67456590dd82f5fa6992d2981f31360d33b2bf..76d8bf5e0849ff994246a9622fa460a4c9cdceff 100644 --- a/src/box/xrow.h +++ b/src/box/xrow.h @@ -339,7 +339,8 @@ iproto_reply_error(struct obuf *out, const struct error *e, uint64_t sync, /** Write error directly to a socket. */ void -iproto_write_error(int fd, const struct error *e, uint32_t schema_version); +iproto_write_error(int fd, const struct error *e, uint32_t schema_version, + uint64_t sync); enum { /* Maximal length of protocol name in handshake */ diff --git a/test/box-py/iproto.result b/test/box-py/iproto.result index 95b39e56fa2c7b9ef81a38cae489753c3ff5d6a7..292aa83e9338fb5c67b9b7fbb4349e7befa64831 100644 --- a/test/box-py/iproto.result +++ b/test/box-py/iproto.result @@ -138,6 +138,7 @@ space2 = box.schema.create_space('test2') Schema changed -> error: True Got another schema_id: True Sync ok +Sync on error is ok space:drop() --- ... diff --git a/test/box-py/iproto.test.py b/test/box-py/iproto.test.py index f545453ae7ef3b3a308562cd047760c2b7d84af0..594c6f45622006986d75cef3ccc757669e289168 100644 --- a/test/box-py/iproto.test.py +++ b/test/box-py/iproto.test.py @@ -301,6 +301,16 @@ if resp['header'][IPROTO_SYNC] == 2334: else: print 'Bad first sync' +# +# Try incorrect JOIN. SYNC must be also returned. +# +body[IPROTO_SERVER_UUID] = 'unknown' +resp = test_request(header, body) +if resp['header'][IPROTO_SYNC] == 2334: + print('Sync on error is ok') +else: + print('Sync on error is not ok') + c.close() admin("space:drop()")