You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by ko...@apache.org on 2019/09/24 18:43:09 UTC

[couchdb-smoosh] branch master updated (8553ee6 -> 78eba84)

This is an automated email from the ASF dual-hosted git repository.

kocolosk pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb-smoosh.git.


    from 8553ee6  Merge pull request #2 from cloudant/fix-compilation-warnings
     new dddaa3c  Support scheduling compactions during time windows
     new 78eba84  Add unit tests for scheduling window logic

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/smoosh_channel.erl                 | 27 ++++++++++++
 src/smoosh_utils.erl                   | 34 ++++++++++++++
 test/exunit/scheduling_window_test.exs | 81 ++++++++++++++++++++++++++++++++++
 test/exunit/test_helper.exs            |  2 +
 4 files changed, 144 insertions(+)
 create mode 100644 test/exunit/scheduling_window_test.exs
 create mode 100644 test/exunit/test_helper.exs


[couchdb-smoosh] 02/02: Add unit tests for scheduling window logic

Posted by ko...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kocolosk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb-smoosh.git

commit 78eba8444c0ba50994c7b686251f3a7c21dc92ce
Author: Adam Kocoloski <ko...@apache.org>
AuthorDate: Wed Sep 11 11:49:37 2019 -0400

    Add unit tests for scheduling window logic
---
 test/exunit/scheduling_window_test.exs | 81 ++++++++++++++++++++++++++++++++++
 test/exunit/test_helper.exs            |  2 +
 2 files changed, 83 insertions(+)

diff --git a/test/exunit/scheduling_window_test.exs b/test/exunit/scheduling_window_test.exs
new file mode 100644
index 0000000..7fa6c23
--- /dev/null
+++ b/test/exunit/scheduling_window_test.exs
@@ -0,0 +1,81 @@
+defmodule SmooshSchedulingWindowTest do
+  use Couch.Test.ExUnit.Case
+
+  alias Couch.Test.Setup
+
+  setup_all(context) do
+    test_ctx = :test_util.start_couch([])
+
+    on_exit(fn ->
+      :config.delete('smoosh.test_channel', 'from')
+      :config.delete('smoosh.test_channel', 'to')
+      :test_util.stop_couch(test_ctx)
+    end)
+
+    context
+  end
+
+  test "in_allowed_window returns true by default", _context do
+    assert :smoosh_utils.in_allowed_window('nonexistent_channel') == true
+  end
+
+  test "in_allowed_window ignores bad input", _context do
+    :config.set('smoosh.test_channel', 'from', 'midnight', false)
+    :config.set('smoosh.test_channel', 'to', 'infinity', false)
+    assert :smoosh_utils.in_allowed_window('test_channel') == true
+  end
+
+  test "in_allowed_window returns false when now < from < to", _context do
+    now = DateTime.utc_now()
+    from = DateTime.add(now, 18_000)
+    to = DateTime.add(now, 36_000)
+    :config.set('smoosh.test_channel', 'from', '#{from.hour}:#{from.minute}', false)
+    :config.set('smoosh.test_channel', 'to', '#{to.hour}:#{to.minute}', false)
+    assert :smoosh_utils.in_allowed_window('test_channel') == false
+  end
+
+  test "in_allowed_window returns true when from < now < to", _context do
+    now = DateTime.utc_now()
+    from = DateTime.add(now, -18_000)
+    to = DateTime.add(now, 18_000)
+    :config.set('smoosh.test_channel', 'from', '#{from.hour}:#{from.minute}', false)
+    :config.set('smoosh.test_channel', 'to', '#{to.hour}:#{to.minute}', false)
+    assert :smoosh_utils.in_allowed_window('test_channel') == true
+  end
+
+  test "in_allowed_window returns false when from < to < now", _context do
+    now = DateTime.utc_now()
+    from = DateTime.add(now, -36_000)
+    to = DateTime.add(now, -18_000)
+    :config.set('smoosh.test_channel', 'from', '#{from.hour}:#{from.minute}', false)
+    :config.set('smoosh.test_channel', 'to', '#{to.hour}:#{to.minute}', false)
+    assert :smoosh_utils.in_allowed_window('test_channel') == false
+  end
+
+  test "in_allowed_window returns true when to < from < now", _context do
+    now = DateTime.utc_now()
+    from = DateTime.add(now, -18_000)
+    to = DateTime.add(now, -36_000)
+    :config.set('smoosh.test_channel', 'from', '#{from.hour}:#{from.minute}', false)
+    :config.set('smoosh.test_channel', 'to', '#{to.hour}:#{to.minute}', false)
+    assert :smoosh_utils.in_allowed_window('test_channel') == true
+  end
+
+  test "in_allowed_window returns false when to < now < from", _context do
+    now = DateTime.utc_now()
+    from = DateTime.add(now, 18_000)
+    to = DateTime.add(now, -18_000)
+    :config.set('smoosh.test_channel', 'from', '#{from.hour}:#{from.minute}', false)
+    :config.set('smoosh.test_channel', 'to', '#{to.hour}:#{to.minute}', false)
+    assert :smoosh_utils.in_allowed_window('test_channel') == false
+  end
+
+  test "in_allowed_window returns true when now < to < from", _context do
+    now = DateTime.utc_now()
+    from = DateTime.add(now, 36_000)
+    to = DateTime.add(now, 18_000)
+    :config.set('smoosh.test_channel', 'from', '#{from.hour}:#{from.minute}', false)
+    :config.set('smoosh.test_channel', 'to', '#{to.hour}:#{to.minute}', false)
+    assert :smoosh_utils.in_allowed_window('test_channel') == true
+  end
+end
diff --git a/test/exunit/test_helper.exs b/test/exunit/test_helper.exs
new file mode 100644
index 0000000..3140500
--- /dev/null
+++ b/test/exunit/test_helper.exs
@@ -0,0 +1,2 @@
+ExUnit.configure(formatters: [JUnitFormatter, ExUnit.CLIFormatter])
+ExUnit.start()


[couchdb-smoosh] 01/02: Support scheduling compactions during time windows

Posted by ko...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

kocolosk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/couchdb-smoosh.git

commit dddaa3cd44b65d90bc9bd73888c19c0f703b7c97
Author: Adam Kocoloski <ko...@apache.org>
AuthorDate: Fri Sep 6 12:10:01 2019 -0400

    Support scheduling compactions during time windows
    
    This patch allows administrators to configure smoosh to only
    execute compactions during a specified time window on a
    per-channel basis. The (partial) configuration looks like
    
    [smoosh]
    db_channels=overnight_channel
    
    [smoosh.overnight_channel]
    from = 22:00
    to = 06:00
    strict_window = true
    
    If `strict_window` is set to true, smoosh will suspend all
    currently running compactions in this channel when leaving the
    time window, and resume them in the next window. If left at the
    default, currently running compactions will be allowed to complete
    but no new compactions will be started until the window is open again.
---
 src/smoosh_channel.erl | 27 +++++++++++++++++++++++++++
 src/smoosh_utils.erl   | 34 ++++++++++++++++++++++++++++++++++
 2 files changed, 61 insertions(+)

diff --git a/src/smoosh_channel.erl b/src/smoosh_channel.erl
index 58d3ce7..d8a8d14 100644
--- a/src/smoosh_channel.erl
+++ b/src/smoosh_channel.erl
@@ -63,6 +63,7 @@ flush(ServerRef) ->
 
 init(Name) ->
     schedule_unpause(),
+    erlang:send_after(60 * 1000, self(), check_window),
     {ok, #state{name=Name}}.
 
 handle_call({last_updated, Object}, _From, State0) ->
@@ -151,6 +152,32 @@ handle_info({Ref, {ok, Pid}}, State0) when is_reference(Ref) ->
             {noreply, State}
     end;
 
+handle_info(check_window, State0) ->
+    {ok, State} = code_change(nil, State0, nil),
+    #state{paused = Paused, name = Name} = State,
+    StrictWindow = smoosh_utils:get(Name, "strict_window", "false"),
+    FinalState = case {not Paused, smoosh_utils:in_allowed_window(Name)} of
+        {false, false} ->
+            % already in desired state
+            State;
+        {true, true} ->
+            % already in desired state
+            State;
+        {false, true} ->
+            % resume is always safe even if we did not previously suspend
+            {reply, ok, NewState} = handle_call(resume, nil, State),
+            NewState;
+        {true, false} ->
+            if StrictWindow =:= "true" ->
+                {reply, ok, NewState} = handle_call(suspend, nil, State),
+                NewState;
+            true ->
+                State#state{paused=true}
+            end
+    end,
+    erlang:send_after(60 * 1000, self(), check_window),
+    {noreply, FinalState};
+
 handle_info(pause, State0) ->
     {ok, State} = code_change(nil, State0, nil),
     {noreply, State#state{paused=true}};
diff --git a/src/smoosh_utils.erl b/src/smoosh_utils.erl
index 78ef83a..b433de0 100644
--- a/src/smoosh_utils.erl
+++ b/src/smoosh_utils.erl
@@ -14,6 +14,9 @@
 -include_lib("couch/include/couch_db.hrl").
 
 -export([get/2, get/3, group_pid/1, split/1, stringify/1, ignore_db/1]).
+-export([
+    in_allowed_window/1
+]).
 
 group_pid({Shard, GroupId}) ->
     case couch_view_group:open_db_group(Shard, GroupId) of
@@ -56,3 +59,34 @@ ignore_db(DbName) when is_list(DbName) ->
     end;
 ignore_db(Db) ->
     ignore_db(couch_db:name(Db)).
+
+in_allowed_window(Channel) ->
+    From = parse_time(get(Channel, "from"), {00, 00}),
+    To = parse_time(get(Channel, "to"), {24, 00}),
+    in_allowed_window(From, To).
+
+in_allowed_window(From, To) ->
+    {HH, MM, _} = erlang:time(),
+    case From < To of
+    true ->
+        ({HH, MM} >= From) andalso ({HH, MM} < To);
+    false ->
+        ({HH, MM} >= From) orelse ({HH, MM} < To)
+    end.
+
+
+parse_time(undefined, Default) ->
+    Default;
+parse_time(String, Default) ->
+    case string:tokens(String, ":") of
+        [HH, MM] ->
+            try
+                {list_to_integer(HH), list_to_integer(MM)}
+            catch error:badarg ->
+                couch_log:error("Malformed compaction schedule configuration: ~s", [String]),
+                Default
+            end;
+        _Else ->
+            couch_log:error("Malformed compaction schedule configuration: ~s", [String]),
+            Default
+    end.