nickva commented on a change in pull request #2857:
URL: https://github.com/apache/couchdb/pull/2857#discussion_r418325821



##########
File path: src/fabric/src/fabric2_db_expiration.erl
##########
@@ -0,0 +1,218 @@
+% Licensed under the Apache License, Version 2.0 (the "License"); you may not
+% use this file except in compliance with the License. You may obtain a copy of
+% the License at
+%
+%   http://www.apache.org/licenses/LICENSE-2.0
+%
+% Unless required by applicable law or agreed to in writing, software
+% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+% License for the specific language governing permissions and limitations under
+% the License.
+
+-module(fabric2_db_expiration).
+
+
+-behaviour(gen_server).
+
+
+-export([
+    start_link/0
+]).
+
+-export([
+    init/1,
+    handle_call/3,
+    handle_cast/2,
+    handle_info/2,
+    terminate/2,
+    code_change/3
+]).
+
+
+-include_lib("couch/include/couch_db.hrl").
+-include_lib("fabric/include/fabric2.hrl").
+
+
+start_link() ->
+    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).
+
+
+init(_) ->
+    start_timer(),
+    {ok, nil}.
+
+
+terminate(_M, _St) ->
+    ok.
+
+
+handle_call(Msg, _From, St) ->
+    {stop, {bad_call, Msg}, {bad_call, Msg}, St}.
+
+
+handle_cast(timeout, St) ->
+    proc_lib:init_ack({ok, self()}),
+    try
+        couch_jobs:set_type_timeout(?DB_EXPIRATION_JOB_TYPE, 6),
+        case add_or_get_job() of
+            ok -> ok;
+            retry -> add_or_get_job()
+        end,
+        case run_loop() of
+            ok -> ok;
+            retry -> run_loop()
+        end,
+        {noreply, St}
+    catch
+        _:_->
+            start_timer(),
+            {noreply, St}
+    end;
+handle_cast(Msg, St) ->
+    {stop, {bad_cast, Msg}, St}.
+
+
+handle_info(Msg, St) ->
+    {stop, {bad_info, Msg}, St}.
+
+
+code_change(_OldVsn, St, _Extra) ->
+    {ok, St}.
+
+
+start_timer() ->
+    After = 10,
+    case timer:apply_after(After, gen_server, cast, [self(), timeout]) of
+        {ok, Ref} ->
+            Ref;
+        _Error ->
+            nil
+    end.
+
+
+add_or_get_job() ->
+    couch_jobs:set_type_timeout(?DB_EXPIRATION_JOB_TYPE, 6),
+    case couch_jobs:get_job_data(
+        undefined,
+        ?DB_EXPIRATION_JOB_TYPE,
+        ?DB_EXPIRATION_JOB
+    ) of
+        {error, not_found} ->
+            couch_jobs:add(
+                undefined,
+                ?DB_EXPIRATION_JOB_TYPE,
+                ?DB_EXPIRATION_JOB,
+                #{}
+            );
+        {ok, _JobData} ->
+            ok
+    end.
+
+
+run_loop() ->
+    {ok, Job, JobData} = couch_jobs:accept(?DB_EXPIRATION_JOB_TYPE),

Review comment:
       Since we sticking with a gen_server (instead of the proc_lib hack), we 
don't want to block during accept so we can 
    say `spawn_monitor` a new process which will run ` {ok, Job, JobData} = 
couch_jobs:accept(?DB_EXPIRATION_JOB_TYPE, #{max_scheduled_time => now_sec()})` 
and exit with the `{Job, JobData}` result or error. To be extra sure we keep 
track of it we can keep the `Ref` in the gen_server state (instead of making it 
nil it could be `#st{acceptor = Ref}` for example.
   
   Then in the main gen_server we'd wait for the 'DOWN' message from the 
acceptor. When we get it we'd call `process_expiration()`, 
`couch_jobs:resubmit(undefined, Job, Now + schedule_sec(), JobData),` and spawn 
another acceptor again and so on.
   
   This way we are more verbose however it's more obvious what is happening
   




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to