From: Konstantin Osipov <kostja@tarantool.org> To: tarantool-patches@freelists.org Cc: vdavydov.dev@gmail.com Subject: Re: [tarantool-patches] [PATCH v2 10/10] session: introduce binary box.session.push Date: Thu, 10 May 2018 22:50:38 +0300 [thread overview] Message-ID: <20180510195038.GJ30593@atlas> (raw) In-Reply-To: <2e8899477ec65522992dd33d246e21c92ebbe246.1524228894.git.v.shpilevoy@tarantool.org> * Vladislav Shpilevoy <v.shpilevoy@tarantool.org> [18/04/20 16:25]: > Box.session.push() allows to send a message to a client with no > finishing a main request. > > Tarantool after this patch supports pushes over binary protocol. > > IProto message is encoded using a new header code - IPROTO_CHUNK. > TX thread to notify IProto thread about new data in obuf sends > a message 'push_msg'. IProto thread, got this message, notifies > libev about new data, and then sends 'push_msg' back with > updated write position. TX thread, received the message back, > updates its version of a write position. If IProto would not send > a write position, then TX would write to the same obuf again and > again, because it can not know that IProto already flushed > another obuf. > > To avoid multiple 'push_msg' in fly between IProto and TX, the > only one 'push_msg' per connection is used. To deliver pushes, > appeared when 'push_msg' was in fly, TX thread sets a flag every > time when sees, that 'push_msg' is sent, and there is a new push. > When 'push_msg' returns, it checks this flag, and if it is set, > the IProto is notified again. I don't see any reason for this restriction. Any connection has two independent rotating output buffers of infinite size. If you ever want to block a push message, you should block it because both buffers are busy. > +/** > + * Message to notify IProto thread about new data in an output > + * buffer. Struct iproto_msg is not used here, because push > + * notification can be much more compact: it does not have > + * request, ibuf, length, flags ... > + */ > +struct iproto_push_msg { > + struct cmsg base; > + /** > + * Before sending to IProto thread, the wpos is set to a > + * current position in an output buffer. Before IProto > + * returns the message to TX, it sets wpos to the last > + * flushed position (works like iproto_msg.wpos). > + */ > + struct iproto_wpos wpos; > +}; > + Looks good to me. > + * Is_push_in_progress is set, when a push_msg is sent to > + * IProto thread, and reset, when the message is returned > + * to TX. If a new push sees, that a push_msg is already > + * sent to IProto, then has_new_pushes is set. After push > + * notification is returned to TX, it checks > + * has_new_pushes. If it is set, then the notification is > + * sent again. This ping-pong continues, until TX stopped > + * pushing. It allows to > + * 1) avoid multiple push_msg from one session in fly, > + * 2) do not block push() until a previous push() is > + * finished. Please make it radically simpler, every push can create a new message which has an independent life cycle. Messages can never run one over each other, so you have nothing to worry about. > @@ -1038,7 +1085,7 @@ tx_process_disconnect(struct cmsg *m) > struct iproto_msg *msg = (struct iproto_msg *) m; > struct iproto_connection *con = msg->connection; > if (con->session) { > - tx_fiber_init(con->session, 0); > + tx_fiber_init(con->session, NULL); Why do you need to make it more complex than it is now? Every Lua procedure which makes a push takes a long-polling reference to the connection already. Until this procedure ends, you can't disconnect a connection. > +static void > +tx_accept_wpos(struct iproto_connection *con, const struct iproto_wpos *wpos) > { > - struct iproto_msg *msg = (struct iproto_msg *) m; > - struct iproto_connection *con = msg->connection; > - > struct obuf *prev = &con->obuf[con->tx.p_obuf == con->obuf]; > - if (msg->wpos.obuf == con->tx.p_obuf) { > + if (wpos->obuf == con->tx.p_obuf) { > /* > * We got a message advancing the buffer which > * is being appended to. The previous buffer is > @@ -1134,6 +1182,13 @@ tx_accept_msg(struct cmsg *m) > */ > con->tx.p_obuf = prev; > } > +} > + > +static inline struct iproto_msg * > +tx_accept_msg(struct cmsg *m) > +{ > + struct iproto_msg *msg = (struct iproto_msg *) m; > + tx_accept_wpos(msg->connection, &msg->wpos); > return msg; > } This somehow looks half-baked, I don't know how yet. > +c:call('push_null', {}, {on_push = on_push}) What happens if on_push handler is not set? Can I get the entire data set in a result when all pushes are over? Can I get a data set as an iterable and yield in the iterator instead? -- Konstantin Osipov, Moscow, Russia, +7 903 626 22 32 http://tarantool.io - www.twitter.com/kostja_osipov
next prev parent reply other threads:[~2018-05-10 19:50 UTC|newest] Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-04-20 13:24 [PATCH v2 00/10] session: introduce box.session.push Vladislav Shpilevoy 2018-04-20 13:24 ` [PATCH v2 01/10] yaml: don't throw OOM on any error in yaml encoding Vladislav Shpilevoy 2018-05-10 18:10 ` [tarantool-patches] " Konstantin Osipov 2018-04-20 13:24 ` [tarantool-patches] [PATCH v2 10/10] session: introduce binary box.session.push Vladislav Shpilevoy 2018-05-10 19:50 ` Konstantin Osipov [this message] 2018-05-24 20:50 ` [tarantool-patches] " Vladislav Shpilevoy 2018-04-20 13:24 ` [PATCH v2 02/10] yaml: introduce yaml.encode_tagged Vladislav Shpilevoy 2018-05-10 18:22 ` [tarantool-patches] " Konstantin Osipov 2018-05-24 20:50 ` [tarantool-patches] " Vladislav Shpilevoy 2018-05-30 19:15 ` Konstantin Osipov 2018-05-30 20:49 ` Vladislav Shpilevoy 2018-05-31 10:46 ` Konstantin Osipov 2018-04-20 13:24 ` [PATCH v2 03/10] yaml: introduce yaml.decode_tag Vladislav Shpilevoy 2018-05-10 18:41 ` [tarantool-patches] " Konstantin Osipov 2018-05-24 20:50 ` [tarantool-patches] " Vladislav Shpilevoy 2018-05-31 10:54 ` Konstantin Osipov 2018-05-31 11:36 ` Konstantin Osipov 2018-04-20 13:24 ` [PATCH v2 04/10] console: use Lua C API to do formatting for console Vladislav Shpilevoy 2018-05-10 18:46 ` [tarantool-patches] " Konstantin Osipov 2018-05-24 20:50 ` [tarantool-patches] " Vladislav Shpilevoy 2018-04-20 13:24 ` [PATCH v2 05/10] session: move salt into iproto connection Vladislav Shpilevoy 2018-05-10 18:47 ` [tarantool-patches] " Konstantin Osipov 2018-04-20 13:24 ` [PATCH v2 06/10] session: introduce session vtab and meta Vladislav Shpilevoy 2018-05-10 19:20 ` [tarantool-patches] " Konstantin Osipov 2018-05-24 20:50 ` [tarantool-patches] " Vladislav Shpilevoy 2018-04-20 13:24 ` [PATCH v2 07/10] port: rename dump() into dump_msgpack() Vladislav Shpilevoy 2018-05-10 19:21 ` [tarantool-patches] " Konstantin Osipov 2018-04-20 13:24 ` [PATCH v2 08/10] session: introduce text box.session.push Vladislav Shpilevoy 2018-05-10 19:27 ` [tarantool-patches] " Konstantin Osipov 2018-05-24 20:50 ` [tarantool-patches] " Vladislav Shpilevoy 2018-04-20 13:24 ` [PATCH v2 09/10] session: enable box.session.push in local console Vladislav Shpilevoy 2018-05-10 19:28 ` [tarantool-patches] " Konstantin Osipov 2018-05-24 20:50 ` [tarantool-patches] [PATCH 1/1] netbox: introduce iterable future objects Vladislav Shpilevoy 2018-06-04 22:17 ` [tarantool-patches] " Vladislav Shpilevoy
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=20180510195038.GJ30593@atlas \ --to=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=vdavydov.dev@gmail.com \ --subject='Re: [tarantool-patches] [PATCH v2 10/10] session: introduce binary box.session.push' \ /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