From: Konstantin Osipov <kostja@tarantool.org> To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> Cc: tarantool-patches@freelists.org Subject: [tarantool-patches] Re: [PATCH 3/5] swim: allow to hang triggers on member updates Date: Wed, 5 Jun 2019 10:11:59 +0300 [thread overview] Message-ID: <20190605071159.GD28736@atlas> (raw) In-Reply-To: <d30754e0bffe31511cdf1bcf7c1255aeb2a663b0.1559433539.git.v.shpilevoy@tarantool.org> * Vladislav Shpilevoy <v.shpilevoy@tarantool.org> [19/06/03 14:33]: I like the design: elegant and lean. Some comments below. > This commit allows to hang triggers on member updates. "hang triggers" sounds ominous. I think you simply meant "set triggers". See also patch subject, please change as well. > struct rlist in_dissemination_queue; > + /** > + * Each time a member is updated, or created, or dropped, > + * it is added to an update queue. Members from this queue > + * are dispatched into user defined triggers. > + */ > + struct stailq_entry in_update_queue; I think the name is a bit confusing. After all, the dissemination queue is also an update queue. in_local_queue? in_trigger_queue? in_event_queue? in_pending_member_update_queue? in_member_update? in_member_update_queue? Please also make sure that all API names continue to agree with each other and internal member names after the rename. > + /** > + * Mask of events happened with this member since a > + * previous trigger invocation. Once the events are > + * delivered into a trigger, the mask is nullified and > + * starts collecting new events. > + */ > + enum swim_ev_mask events; Since you use 'events' for an associated mask, perhaps in_event_queue or in_local_event_queue is good enough. > + /** > + * Worker fiber to serve member update triggers. This task > + * is being done in a separate fiber, because user > + * triggers can yield and libev callbacks, processing > + * member updates, are not allowed to yield. > + */ > + struct fiber *worker; I think as long as the worker is only used for triggers, the name should be more specific. when the worker is used for other events or actions, it could be renamed. > @@ -734,7 +801,6 @@ swim_delete_member(struct swim *swim, struct swim_member *member) > mh_int_t rc = mh_swim_table_find(swim->members, key, NULL); > assert(rc != mh_end(swim->members)); > mh_swim_table_del(swim->members, rc, NULL); > - swim_cached_round_msg_invalidate(swim); > rlist_del_entry(member, in_round_queue); Stray change? At least I don't understand it. > + struct swim *s = va_arg(va, struct swim *); > + struct swim_on_member_update_ctx ctx; > + while (! fiber_is_cancelled()) { > + while (stailq_empty(&s->update_queue)) { > + fiber_yield(); > + if (fiber_is_cancelled()) > + goto end; > + } Since you use goto anyway, why a double loop? while (! fiber_is_cancelled()) { if (stailq_empty(&s->update_queue) { fiber_yield(); continue; } ... } > + } > +end: > + swim_do_delete(s); I don't mind swim_do_delete(), but I think the worker should not be destorying the instance. Looks a breach of encapsulation, this assumes the workers knows about all other uses of struct swim. Why not cancel and join the worker from the destructor and then safely do the delete? > + swim->worker = fiber_new("SWIM worker", swim_worker_f); > + if (swim->worker == NULL) { > + free(swim); > + return NULL; > + } > swim->members = mh_swim_table_new(); > if (swim->members == NULL) { > + fiber_cancel(swim->worker); Better to start the worker last, then you will have easy time destroying it on failure. This is a minor nit, ignore if you wish. > free(swim); > diag_set(OutOfMemory, sizeof(*swim->members), > "mh_swim_table_new", "members"); > @@ -1700,7 +1832,10 @@ swim_new(void) > @@ -1951,17 +2088,19 @@ swim_size(const struct swim *swim) > return mh_size(swim->members); > } > > > +void > +swim_delete(struct swim *swim) > +{ > + fiber_wakeup(swim->worker); > + fiber_cancel(swim->worker); > + fiber_sleep(0); This looks like a hack, please cancel and join the worker instead. > @@ -1991,7 +2139,8 @@ swim_quit_step_complete(struct swim_task *task, > (void) rc; > struct swim *swim = swim_by_scheduler(scheduler); > if (rlist_empty(&swim->round_queue)) { > - swim_delete(swim); > + fiber_wakeup(swim->worker); > + fiber_cancel(swim->worker); > return; And now this code implicitly destroys the swim instance, which is hard to follow when reading. -- Konstantin Osipov, Moscow, Russia
next prev parent reply other threads:[~2019-06-05 12:07 UTC|newest] Thread overview: 20+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-06-02 0:00 [tarantool-patches] [PATCH 0/5] SWIM on_member_update Vladislav Shpilevoy 2019-06-02 0:00 ` [tarantool-patches] [PATCH 1/5] test: create isolated ev_loop for swim unit tests Vladislav Shpilevoy 2019-06-05 6:51 ` [tarantool-patches] " Konstantin Osipov 2019-06-05 21:53 ` Vladislav Shpilevoy 2019-06-08 14:24 ` Konstantin Osipov 2019-06-02 0:00 ` [tarantool-patches] [PATCH 2/5] swim: fix a 'use after free' in SWIM tests Vladislav Shpilevoy 2019-06-05 6:52 ` [tarantool-patches] " Konstantin Osipov 2019-06-02 0:00 ` [tarantool-patches] [PATCH 3/5] swim: allow to hang triggers on member updates Vladislav Shpilevoy 2019-06-05 7:11 ` Konstantin Osipov [this message] 2019-06-05 21:53 ` [tarantool-patches] " Vladislav Shpilevoy 2019-06-07 13:35 ` Konstantin Osipov 2019-06-02 0:00 ` [tarantool-patches] [PATCH 4/5] swim: call swim:new/delete via Lua C, not via FFI Vladislav Shpilevoy 2019-06-08 14:24 ` [tarantool-patches] " Konstantin Osipov 2019-06-02 0:10 ` [tarantool-patches] [PATCH 5/5] swim: expose Lua triggers on member update Vladislav Shpilevoy 2019-06-05 21:54 ` [tarantool-patches] " Vladislav Shpilevoy 2019-06-08 14:29 ` Konstantin Osipov [not found] ` <12b8ea76f7c1cd100a80ddcea3c29d20354e073e.1559433539.git.v.shpilevoy@tarantool.org> 2019-06-08 14:27 ` Konstantin Osipov 2019-06-08 19:52 ` Vladislav Shpilevoy 2019-06-09 5:15 ` Konstantin Osipov 2019-06-09 16:41 ` 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=20190605071159.GD28736@atlas \ --to=kostja@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=v.shpilevoy@tarantool.org \ --subject='[tarantool-patches] Re: [PATCH 3/5] swim: allow to hang triggers on member updates' \ /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