You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@couchdb.apache.org by va...@apache.org on 2020/09/15 20:14:01 UTC
[couchdb] 04/16: Add fold_jobs/4 and pending_count/2,
3 to couch_jobs API
This is an automated email from the ASF dual-hosted git repository.
vatamane pushed a commit to branch prototype/fdb-layer
in repository https://gitbox.apache.org/repos/asf/couchdb.git
commit d2c9dffa3aca3b3e2faed49526b0065ebb845fad
Author: Nick Vatamaniuc <va...@apache.org>
AuthorDate: Fri Aug 28 04:30:53 2020 -0400
Add fold_jobs/4 and pending_count/2,3 to couch_jobs API
fold_jobs/4 is a generalized folding API which can be used to process all the
jobs of a particular type.
get_pending_count/2,3 can be used to get the count of pending jobs. It takes
the same options as accept, including a limit and `max_sched_time`. Just like
accept it reads the range of pending jobs as a snapshot to avoid generating
read conflicts.
---
src/couch_jobs/src/couch_jobs.erl | 37 +++++++++++++++++++++++++++----
src/couch_jobs/src/couch_jobs_pending.erl | 32 +++++++++++++++++++++-----
2 files changed, 59 insertions(+), 10 deletions(-)
diff --git a/src/couch_jobs/src/couch_jobs.erl b/src/couch_jobs/src/couch_jobs.erl
index f5d6a7b..6c40f5d 100644
--- a/src/couch_jobs/src/couch_jobs.erl
+++ b/src/couch_jobs/src/couch_jobs.erl
@@ -17,10 +17,15 @@
add/4,
add/5,
remove/3,
+
+ % Job monitoring
+ get_types/1,
get_job_data/3,
get_job_state/3,
get_active_jobs_ids/2,
- get_types/1,
+ fold_jobs/4,
+ pending_count/2,
+ pending_count/3,
% Job processing
accept/1,
@@ -80,6 +85,13 @@ remove(Tx, Type, JobId) when is_binary(JobId) ->
end).
+-spec get_types(jtx()) -> [job_type()] | {error, any()}.
+get_types(Tx) ->
+ couch_jobs_fdb:tx(couch_jobs_fdb:get_jtx(Tx), fun(JTx) ->
+ couch_jobs_fdb:get_types(JTx)
+ end).
+
+
-spec get_job_data(jtx(), job_type(), job_id()) -> {ok, job_data()} | {error,
any()}.
get_job_data(Tx, Type, JobId) when is_binary(JobId) ->
@@ -116,10 +128,27 @@ get_active_jobs_ids(Tx, Type) ->
end).
--spec get_types(jtx()) -> [job_type()] | {error, any()}.
-get_types(Tx) ->
+-spec fold_jobs(jtx(), job_type(), fun(), any()) -> any().
+fold_jobs(Tx, Type, Fun, UserAcc) when is_function(Fun, 5) ->
couch_jobs_fdb:tx(couch_jobs_fdb:get_jtx(Tx), fun(JTx) ->
- couch_jobs_fdb:get_types(JTx)
+ maps:fold(fun(JobId, {_Seq, JobState, DataEnc}, Acc) ->
+ Data = couch_jobs_fdb:decode_data(DataEnc),
+ Fun(JTx, JobId, JobState, Data, Acc)
+ end, UserAcc, couch_jobs_fdb:get_jobs(JTx, Type))
+ end).
+
+
+-spec pending_count(jtx(), job_type()) -> integer().
+pending_count(Tx, Type) ->
+ pending_count(Tx, Type, #{}).
+
+
+-spec pending_count(jtx(), job_type(), #{}) -> integer().
+pending_count(Tx, Type, Opts) ->
+ MaxSTime = maps:get(max_sched_time, Opts, ?UNDEFINED_MAX_SCHEDULED_TIME),
+ Limit = maps:get(limit, Opts, 1024),
+ couch_jobs_fdb:tx(couch_jobs_fdb:get_jtx(Tx), fun(JTx) ->
+ couch_jobs_pending:pending_count(JTx, Type, MaxSTime, Limit)
end).
diff --git a/src/couch_jobs/src/couch_jobs_pending.erl b/src/couch_jobs/src/couch_jobs_pending.erl
index ab53c59..a85f2fc 100644
--- a/src/couch_jobs/src/couch_jobs_pending.erl
+++ b/src/couch_jobs/src/couch_jobs_pending.erl
@@ -16,7 +16,8 @@
-export([
enqueue/4,
dequeue/4,
- remove/4
+ remove/4,
+ pending_count/4
]).
@@ -47,16 +48,14 @@ dequeue(#{jtx := true} = JTx, Type, _, true) ->
{ok, JobId}
end;
-dequeue(#{jtx := true} = JTx, Type, MaxPriority, _) ->
+dequeue(#{jtx := true} = JTx, Type, MaxSTime, _) ->
#{tx := Tx, jobs_path := Jobs} = JTx,
- Prefix = erlfdb_tuple:pack({?PENDING, Type}, Jobs),
- StartKeySel = erlfdb_key:first_greater_than(Prefix),
- End = erlfdb_tuple:pack({MaxPriority, <<16#FF>>}, Prefix),
- EndKeySel = erlfdb_key:first_greater_or_equal(End),
+ {StartKeySel, EndKeySel} = get_range_selectors(JTx, Type, MaxSTime),
case clear_random_key_from_range(Tx, StartKeySel, EndKeySel) of
{error, not_found} ->
{not_found, get_pending_watch(JTx, Type)};
{ok, PendingKey} ->
+ Prefix = erlfdb_tuple:pack({?PENDING, Type}, Jobs),
{_, JobId} = erlfdb_tuple:unpack(PendingKey, Prefix),
{ok, JobId}
end.
@@ -68,8 +67,29 @@ remove(#{jtx := true} = JTx, Type, JobId, STime) ->
erlfdb:clear(Tx, Key).
+pending_count(#{jtx := true} = JTx, Type, MaxSTime, Limit) ->
+ #{tx := Tx} = JTx,
+ Opts = [
+ {limit, Limit},
+ {snapshot, true},
+ {streaming_mode, want_all}
+ ],
+ {StartSel, EndSel} = get_range_selectors(JTx, Type, MaxSTime),
+ FoldFun = fun(_Row, Cnt) -> Cnt + 1 end,
+ erlfdb:fold_range(Tx, StartSel, EndSel, FoldFun, 0, Opts).
+
+
%% Private functions
+% Get pending key selectors, taking into account max scheduled time value.
+get_range_selectors(#{jtx := true} = JTx, Type, MaxSTime) ->
+ #{jobs_path := Jobs} = JTx,
+ Prefix = erlfdb_tuple:pack({?PENDING, Type}, Jobs),
+ StartKeySel = erlfdb_key:first_greater_than(Prefix),
+ End = erlfdb_tuple:pack({MaxSTime, <<16#FF>>}, Prefix),
+ EndKeySel = erlfdb_key:first_greater_or_equal(End),
+ {StartKeySel, EndKeySel}.
+
% Pick a random item from the range without reading the keys in first. However
% the constraint it that IDs should looks like random UUIDs