Tarantool development patches archive
 help / color / mirror / Atom feed
From: Cyrill Gorcunov via Tarantool-patches <tarantool-patches@dev.tarantool.org>
To: Serge Petrenko <sergepetrenko@tarantool.org>
Cc: v.shpilevoy@tarantool.org, tarantool-patches@dev.tarantool.org
Subject: Re: [Tarantool-patches] [PATCH v2] wal: introduce limits on simultaneous writes
Date: Mon, 15 Feb 2021 14:17:59 +0300	[thread overview]
Message-ID: <YCpYZ/K8V8ePZvSD@grain> (raw)
In-Reply-To: <20210211121750.46298-1-sergepetrenko@tarantool.org>

On Thu, Feb 11, 2021 at 03:17:50PM +0300, Serge Petrenko wrote:
> diff --git a/src/box/applier.cc b/src/box/applier.cc
> index 553db76fc..06aaa0a79 100644
> --- a/src/box/applier.cc
> +++ b/src/box/applier.cc
> @@ -967,6 +967,15 @@ applier_apply_tx(struct applier *applier, struct stailq *rows)
>  		goto success;
>  	}
>  
> +	/*
> +	 * Do not spam WAL with excess write requests, let it process what's
> +	 * piled up first.
> +	 * This is done before opening the transaction to avoid problems with
> +	 * yielding inside it.
> +	 */
> +	if (journal_queue_is_full(current_journal))
> +		journal_wait_queue();
> +

Serge, just a few comments, feel free to ignore.

Maybe it would be better to pass current_journal to journal_wait_queue,
otherwise it looks somehow inconsistent, no?

	if (journal_queue_is_full(current_journal))
		journal_wait_queue(current_journal);

Actually I would name journal queue engine as plain journalq, this would
look like

	if (journalq_is_full(current_journal))
		journalq_wait(current_journal);

But it is very humble pov, lets stick with long `journal_queue`.
...
> +/** Wake the journal queue up. */
> +static inline void
> +journal_queue_wakeup(struct journal *j, bool force_ready)
> +{
> +	assert(j == current_journal);

Seems this assert is not needed. The overall idea of passing
journal as an argument is quite the reverse, ie to work with
any journal. This is not a blocker, could be cleaned up on top
or simply ignored.

> +	assert(!rlist_empty(&j->waiters));
> +	if (j->queue_is_woken)
> +		return;
> +	j->queue_is_woken = true;
> +	journal_queue_wakeup_next(&j->waiters, force_ready);
> +}
> +
> +/**
> + * Check whether any of the queue size limits is reached.
> + * If the queue is full, we must wait for some of the entries to be written
> + * before proceeding with a new asynchronous write request.
> + */
> +static inline bool
> +journal_queue_is_full(struct journal *j)
> +{
> +	assert(j == current_journal);

same, no need for assert()

> +	return (j->queue_max_size != 0 && j->queue_size >= j->queue_max_size) ||
> +	       (j->queue_max_len != 0 && j->queue_len >= j->queue_max_len);
> +}
> +
> +/**
> + * Check whether anyone is waiting for the journal queue to empty. If there are
> + * other waiters we must go after them to preserve write order.
> + */
> +static inline bool
> +journal_queue_has_waiters(struct journal *j)
> +{
> +	assert(j == current_journal);

same, no need for assert()

> +	return !rlist_empty(&j->waiters);
> +}
> +
> +/** Yield until there's some space in the journal queue. */
> +void
> +journal_wait_queue(void);
> +
>  /**
>   * Complete asynchronous write.
>   */
> @@ -131,15 +199,15 @@ static inline void
>  journal_async_complete(struct journal_entry *entry)
>  {
>  	assert(entry->write_async_cb != NULL);
> +	current_journal->queue_len--;
> +	current_journal->queue_size -= entry->approx_len;

Myabe worth to make queue ops closed into some helper? Because
length and size can't be updated without a tangle. IOW, something
like

static inline void
journal_queue_attr_dec(struct journal *j, struct journal_entry *entry)
{
	j->queue_len--;
	j->queue_size -= entry->approx_len;
}

static inline void
journal_queue_attr_inc(struct journal *j, struct journal_entry *entry)
{
	j->queue_len++;
	j->queue_size += entry->approx_len;
}

Again, this is my pov, **free to ignore**. attr here stands for
attributes because queue_len and queue_size are not the queue
itself but attributes which controls when we need to wait
data to be flushed.

> +	assert(current_journal->queue_len >= 0);
> +	assert(current_journal->queue_size >= 0);
> +	if (journal_queue_has_waiters(current_journal))
> +		journal_queue_wakeup(current_journal, false);
>  	entry->write_async_cb(entry);
>  }

  reply	other threads:[~2021-02-15 11:18 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-11 12:17 Serge Petrenko via Tarantool-patches
2021-02-15 11:17 ` Cyrill Gorcunov via Tarantool-patches [this message]
2021-02-16 12:47   ` Serge Petrenko via Tarantool-patches
2021-02-16 12:49     ` Cyrill Gorcunov via Tarantool-patches
2021-02-17 20:46 ` Vladislav Shpilevoy via Tarantool-patches
2021-02-18 20:06   ` Serge Petrenko via Tarantool-patches
2021-02-23 22:19     ` Vladislav Shpilevoy via Tarantool-patches
2021-02-24 19:32       ` Serge Petrenko via Tarantool-patches
2021-02-26  0:58         ` Vladislav Shpilevoy via Tarantool-patches

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=YCpYZ/K8V8ePZvSD@grain \
    --to=tarantool-patches@dev.tarantool.org \
    --cc=gorcunov@gmail.com \
    --cc=sergepetrenko@tarantool.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH v2] wal: introduce limits on simultaneous writes' \
    /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