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/06 16:42:40 UTC

[couchdb-smoosh] branch scheduled-smoosh created (now 1cf2048)

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

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


      at 1cf2048  Support scheduling compactions during time windows

This branch includes the following new commits:

     new 1cf2048  Support scheduling compactions during time windows

The 1 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.



[couchdb-smoosh] 01/01: 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 scheduled-smoosh
in repository https://gitbox.apache.org/repos/asf/couchdb-smoosh.git

commit 1cf2048bb6ca7bf0e820a4a67a52109904f4295c
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   | 33 +++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/src/smoosh_channel.erl b/src/smoosh_channel.erl
index 58d3ce7..a6269fc 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 {Paused, smoosh_utils:check_window(Name)} of
+        {true, pause} ->
+            % already in desired state
+            State;
+        {false, resume} ->
+            % already in desired state
+            State;
+        {true, resume} ->
+            % resume is always safe even if we did not previously suspend
+            {reply, ok, NewState} = handle_call(resume, nil, State),
+            NewState;
+        {false, pause} ->
+            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..32c90db 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([
+    check_window/1
+]).
 
 group_pid({Shard, GroupId}) ->
     case couch_view_group:open_db_group(Shard, GroupId) of
@@ -56,3 +59,33 @@ ignore_db(DbName) when is_list(DbName) ->
     end;
 ignore_db(Db) ->
     ignore_db(couch_db:name(Db)).
+
+check_window(Channel) ->
+    From = parse_time(get(Channel, "from"), {00, 00}),
+    To = parse_time(get(Channel, "to"), {24, 00}),
+    check_window(From, To).
+
+check_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.