@@ -40,24 +40,42 @@ class basic_handler
4040 return 0 ;
4141 }
4242
43+ // Used by old (protocol-dependent) mechanic, must be removed after refactoring
4344 basic_handler (std::unique_ptr<dnet_logger> logger, async_generic_result &result) :
4445 m_logger (std::move(logger)),
4546 m_handler (result), m_completed(0 ), m_total(0 )
4647 {
48+ memset (&m_addr, 0 , sizeof (dnet_addr));
49+ memset (&m_cmd, 0 , sizeof (dnet_cmd));
4750 }
4851
49- bool handle (dnet_addr *addr, dnet_cmd *cmd)
52+ basic_handler (const dnet_addr &addr, const dnet_cmd &cmd,
53+ std::unique_ptr<dnet_logger> logger, async_generic_result &result) :
54+ m_addr (addr),
55+ m_cmd (cmd),
56+ m_logger (std::move(logger)),
57+ m_handler (result), m_completed(0 ), m_total(0 )
5058 {
51- if (is_trans_destroyed (cmd)) {
52- return increment_completed ();
53- }
59+ }
5460
61+ void log_reply_info (dnet_addr *addr, dnet_cmd *cmd)
62+ {
5563 DNET_LOG (m_logger, cmd->status ? DNET_LOG_ERROR : DNET_LOG_NOTICE, " {}: {}: handled reply from: {}, "
5664 " trans: {}, cflags: {}, status: {}, "
5765 " size: {}, client: {}, last: {}" ,
5866 dnet_dump_id (&cmd->id ), dnet_cmd_string (cmd->cmd ), addr ? dnet_addr_string (addr) : " <unknown>" ,
5967 cmd->trans , dnet_flags_dump_cflags (cmd->flags ), int (cmd->status ), cmd->size ,
6068 !(cmd->flags & DNET_FLAGS_REPLY), !(cmd->flags & DNET_FLAGS_MORE));
69+ }
70+
71+ // Used by old (protocol-dependent) mechanic, must be removed after refactoring
72+ bool handle (dnet_addr *addr, dnet_cmd *cmd)
73+ {
74+ if (is_trans_destroyed (cmd)) {
75+ return increment_completed ();
76+ }
77+
78+ log_reply_info (addr, cmd);
6179
6280 auto data = std::make_shared<callback_result_data>(addr, cmd);
6381
@@ -71,6 +89,29 @@ class basic_handler
7189 return false ;
7290 }
7391
92+ int on_reply (const std::shared_ptr<void > &result)
93+ {
94+ // TODO(sabramkin): Output only protocol-independent known info (currently old-mechanic logging used)
95+ log_reply_info (&m_addr, &m_cmd);
96+
97+ auto data = std::make_shared<n2_callback_result_data>(m_addr, m_cmd, result, 0 );
98+ callback_result_entry entry (data);
99+ m_handler.process (entry);
100+ return 0 ;
101+ }
102+
103+ int on_reply_error (int err)
104+ {
105+ // TODO(sabramkin): Output only protocol-independent known info (currently old-mechanic logging used)
106+ log_reply_info (&m_addr, &m_cmd);
107+
108+ auto data = std::make_shared<n2_callback_result_data>(m_addr, m_cmd, nullptr , err);
109+ data->error = create_error (err, " n2 lookup_new error" ); // TODO(sabramkin): rework error
110+ callback_result_entry entry (data);
111+ m_handler.process (entry);
112+ return 0 ;
113+ }
114+
74115 // how many independent transactions share this handler plus call below
75116 // call below and corresponding +1 is needed, since transactions can be completed
76117 // before send_impl() calls this method to setup this 'reference counter'
@@ -92,6 +133,8 @@ class basic_handler
92133 return false ;
93134 }
94135
136+ dnet_addr m_addr;
137+ dnet_cmd m_cmd;
95138 std::unique_ptr<dnet_logger> m_logger;
96139 async_result_handler<callback_result_entry> m_handler;
97140 std::atomic_size_t m_completed;
@@ -100,13 +143,20 @@ class basic_handler
100143
101144} // namespace detail
102145
146+ const dnet_addr &get_destination_addr (session &sess)
147+ {
148+ const auto fwd = sess.get_forward ();
149+ if (fwd.is_valid ())
150+ return fwd.to_raw ();
151+ return sess.get_direct_address ().to_raw ();
152+ }
153+
103154template <typename Method, typename T>
104155async_generic_result send_impl (session &sess, T &control, Method method)
105156{
106157 async_generic_result result (sess);
107158
108159 detail::basic_handler *handler = new detail::basic_handler (sess.get_logger (), result);
109-
110160 control.complete = detail::basic_handler::handler;
111161 control.priv = handler;
112162
@@ -142,6 +192,42 @@ async_generic_result send_to_single_state(session &sess, dnet_io_control &contro
142192 return send_impl (sess, control, send_to_single_state_io_impl);
143193}
144194
195+ template <typename Method>
196+ async_generic_result n2_send_impl (session &sess, const n2_request &request, Method method)
197+ {
198+ async_generic_result result (sess);
199+
200+ auto handler = std::make_shared<detail::basic_handler>(get_destination_addr (sess), request.cmd ,
201+ sess.get_logger (), result);
202+ n2_request_info request_info{ request, n2_repliers () };
203+
204+ request_info.repliers .on_reply =
205+ [handler](const std::shared_ptr<void > &result){
206+ return handler->on_reply (result);
207+ };
208+ request_info.repliers .on_reply_error =
209+ [handler](int err){
210+ return handler->on_reply_error (err);
211+ };
212+
213+ const size_t count = method (sess, std::move (request_info));
214+ handler->set_total (count);
215+ return result;
216+ }
217+
218+ int n2_trans_alloc_send (dnet_session *s, n2_request_info &&request_info); // implemented in trans.cpp
219+
220+ static size_t n2_send_to_single_state_impl (session &sess, n2_request_info &&request_info)
221+ {
222+ n2_trans_alloc_send (sess.get_native (), std::move (request_info));
223+ return 1 ;
224+ }
225+
226+ async_generic_result n2_send_to_single_state (session &sess, const n2_request &request)
227+ {
228+ return n2_send_impl (sess, request, n2_send_to_single_state_impl);
229+ }
230+
145231static size_t send_to_each_backend_impl (session &sess, dnet_trans_control &ctl)
146232{
147233 return dnet_request_cmd (sess.get_native (), &ctl);
0 commit comments