Skip to content

Commit 63d93d7

Browse files
drewdzzzalyapunov
authored andcommitted
Client: rewrite response decoding logic with new decoder
The commit rewrites response decoding logic using new decoder. Field IPROTO_ERROR_24 is not parsed anymore - it is a duplicate of the last error message in the error stack. Also, the whole error stack is decoded now (before the patch, only the first value was decoded). MP_ERROR_FIELDS are still not decoded. Public structure `Data` is reworked. Now you need to call `data.decode` method and pass a container of arrays - every tuple will be decoded as an array and put to the container.
1 parent 38832d9 commit 63d93d7

File tree

7 files changed

+163
-674
lines changed

7 files changed

+163
-674
lines changed

examples/Reader.hpp

Lines changed: 3 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ struct UserTuple {
4141
uint64_t field1;
4242
std::string field2;
4343
double field3;
44+
45+
static constexpr auto mpp = std::make_tuple(
46+
&UserTuple::field1, &UserTuple::field2, &UserTuple::field3);
4447
};
4548
//doclabel13-2
4649

@@ -50,59 +53,3 @@ operator<<(std::ostream& strm, const UserTuple &t)
5053
return strm << "Tuple: field1=" << t.field1 << " field2=" << t.field2 <<
5154
" field3=" << t.field3;
5255
}
53-
54-
using Buf_t = tnt::Buffer<16 * 1024>;
55-
using BufIter_t = typename Buf_t::iterator;
56-
57-
//doclabel14-1
58-
struct UserTupleValueReader : mpp::DefaultErrorHandler {
59-
explicit UserTupleValueReader(UserTuple& t) : tuple(t) {}
60-
static constexpr mpp::Family VALID_TYPES = mpp::MP_INT | mpp::MP_STR | mpp::MP_FLT;
61-
template <class T>
62-
void Value(BufIter_t&, mpp::compact::Family, T v)
63-
{
64-
if constexpr (std::is_integral_v<T>) {
65-
tuple.field1 = v;
66-
} else {
67-
static_assert(std::is_floating_point_v<T>);
68-
tuple.field3 = v;
69-
}
70-
}
71-
void Value(BufIter_t& itr, mpp::compact::Family, mpp::StrValue v)
72-
{
73-
BufIter_t tmp = itr;
74-
tmp += v.offset;
75-
std::string &dst = tuple.field2;
76-
while (v.size) {
77-
dst.push_back(*tmp);
78-
++tmp;
79-
--v.size;
80-
}
81-
}
82-
void WrongType(mpp::Family expected, mpp::Family got)
83-
{
84-
std::cout << "expected type is " << expected <<
85-
" but got " << got << std::endl;
86-
}
87-
88-
BufIter_t* StoreEndIterator() { return nullptr; }
89-
UserTuple& tuple;
90-
};
91-
//doclabel14-2
92-
93-
//doclabel15-1
94-
template <class BUFFER>
95-
struct UserTupleReader : mpp::SimpleReaderBase<BUFFER, mpp::MP_ARR> {
96-
97-
UserTupleReader(mpp::Dec<BUFFER>& d, UserTuple& t) : dec(d), tuple(t) {}
98-
99-
void Value(const iterator_t<BUFFER>&, mpp::compact::Family, mpp::ArrValue u)
100-
{
101-
assert(u.size == 3);
102-
(void) u;
103-
dec.SetReader(false, UserTupleValueReader{tuple});
104-
}
105-
mpp::Dec<BUFFER>& dec;
106-
UserTuple& tuple;
107-
};
108-
//doclabel15-2

examples/Simple.cpp

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,32 +58,24 @@ using Buf_t = tnt::Buffer<16 * 1024>;
5858
using Net_t = LibevNetProvider<Buf_t, DefaultStream>;
5959
//doclabel02-2
6060

61-
//doclabel16-1
61+
//doclabel14-1
6262
template <class BUFFER>
6363
std::vector<UserTuple>
64-
decodeUserTuple(BUFFER &buf, Data<BUFFER> &data)
64+
decodeUserTuple(Data<BUFFER> &data)
6565
{
6666
std::vector<UserTuple> results;
67-
for(auto& t: data.tuples) {
68-
UserTuple tuple;
69-
mpp::Dec dec(buf);
70-
dec.SetPosition(t.begin);
71-
dec.SetReader(false, UserTupleReader<BUFFER>{dec, tuple});
72-
mpp::ReadResult_t res = dec.Read();
73-
assert(res == mpp::READ_SUCCESS);
74-
(void) res;
75-
results.push_back(tuple);
76-
}
67+
bool ok = data.decode(results);
68+
assert(ok);
7769
return results;
7870
}
79-
//doclabel16-2
71+
//doclabel14-2
8072

8173
template<class BUFFER>
8274
void
83-
printResponse(Connection<BUFFER, Net_t> &conn, Response<BUFFER> &response)
75+
printResponse(Response<BUFFER> &response)
8476
{
8577
if (response.body.error_stack != std::nullopt) {
86-
Error err = (*response.body.error_stack).error;
78+
Error err = (*response.body.error_stack)[0];
8779
std::cout << "RESPONSE ERROR: msg=" << err.msg <<
8880
" line=" << err.file << " file=" << err.file <<
8981
" errno=" << err.saved_errno <<
@@ -92,12 +84,11 @@ printResponse(Connection<BUFFER, Net_t> &conn, Response<BUFFER> &response)
9284
}
9385
if (response.body.data != std::nullopt) {
9486
Data<BUFFER>& data = *response.body.data;
95-
if (data.tuples.empty()) {
87+
std::vector<UserTuple> tuples = decodeUserTuple(data);
88+
if (tuples.empty()) {
9689
std::cout << "Empty result" << std::endl;
9790
return;
9891
}
99-
std::vector<UserTuple> tuples =
100-
decodeUserTuple(conn.getInBuf(), data);
10192
for (auto const& t : tuples) {
10293
std::cout << t << std::endl;
10394
}
@@ -204,7 +195,7 @@ main()
204195
* rely on response code storing in the header or check
205196
* Response->body.data and Response->body.error_stack members.
206197
*/
207-
printResponse<Buf_t>(conn, *response);
198+
printResponse<Buf_t>(*response);
208199
//doclabel11-2
209200
/* Let's wait for both futures at once. */
210201
std::vector<rid_t> futures(2);
@@ -216,7 +207,7 @@ main()
216207
assert(conn.futureIsReady(futures[i]));
217208
response = conn.getResponse(futures[i]);
218209
assert(response != std::nullopt);
219-
printResponse<Buf_t>(conn, *response);
210+
printResponse<Buf_t>(*response);
220211
}
221212
//doclabel11-3
222213
/* Let's create another connection. */

src/Client/ResponseDecoder.hpp

Lines changed: 9 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,8 @@ static constexpr size_t MP_RESPONSE_SIZE = 5;
5151
template<class BUFFER>
5252
class ResponseDecoder {
5353
public:
54-
ResponseDecoder(BUFFER &buf) : m_Dec(buf) {};
54+
ResponseDecoder(BUFFER &buf) : it(buf.begin()) {};
55+
ResponseDecoder(iterator_t<BUFFER> &itr) : it(itr) {};
5556
~ResponseDecoder() { };
5657
ResponseDecoder() = delete;
5758
ResponseDecoder(const ResponseDecoder& decoder) = delete;
@@ -62,57 +63,31 @@ class ResponseDecoder {
6263
void reset(iterator_t<BUFFER> &itr);
6364

6465
private:
65-
int decodeHeader(Header &header);
66-
int decodeBody(Body<BUFFER> &body);
67-
mpp::Dec<BUFFER> m_Dec;
66+
iterator_t<BUFFER> it;
6867
};
6968

7069
template<class BUFFER>
7170
int
7271
ResponseDecoder<BUFFER>::decodeResponseSize()
7372
{
7473
int size = -1;
75-
m_Dec.SetReader(false, mpp::SimpleReader<BUFFER, mpp::MP_INT, int>{size});
76-
mpp::ReadResult_t res = m_Dec.Read();
74+
bool ok = mpp::decode(it, size);
7775
//TODO: raise more detailed error
78-
if (res != mpp::READ_SUCCESS)
76+
if (!ok)
7977
return -1;
8078
return size;
8179
}
8280

83-
template<class BUFFER>
84-
int
85-
ResponseDecoder<BUFFER>::decodeHeader(Header &header)
86-
{
87-
m_Dec.SetReader(false, HeaderReader{m_Dec, header});
88-
mpp::ReadResult_t res = m_Dec.Read();
89-
if (res != mpp::READ_SUCCESS)
90-
return -1;
91-
return 0;
92-
}
93-
94-
template<class BUFFER>
95-
int
96-
ResponseDecoder<BUFFER>::decodeBody(Body<BUFFER> &body)
97-
{
98-
m_Dec.SetReader(false, BodyReader{m_Dec, body});
99-
mpp::ReadResult_t res = m_Dec.Read();
100-
if (res != mpp::READ_SUCCESS)
101-
return -1;
102-
if (body.data != std::nullopt)
103-
body.data->end = m_Dec.getPosition();
104-
return 0;
105-
}
106-
10781
template<class BUFFER>
10882
int
10983
ResponseDecoder<BUFFER>::decodeResponse(Response<BUFFER> &response)
11084
{
111-
if (decodeHeader(response.header) != 0) {
85+
/* Decode header and body separately to get more detailed error. */
86+
if (!mpp::decode(it, response.header)) {
11287
LOG_ERROR("Failed to decode header");
11388
return -1;
11489
}
115-
if (decodeBody(response.body) != 0) {
90+
if (!mpp::decode(it, response.body)) {
11691
LOG_ERROR("Failed to decode body");
11792
return -1;
11893
}
@@ -123,7 +98,7 @@ template<class BUFFER>
12398
void
12499
ResponseDecoder<BUFFER>::reset(iterator_t<BUFFER> &itr)
125100
{
126-
m_Dec.SetPosition(itr);
101+
it = itr;
127102
}
128103

129104
static inline uint32_t

0 commit comments

Comments
 (0)