summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Vatamaniuc <vatamane@apache.org>2017-10-03 02:14:22 -0400
committerNick Vatamaniuc <nickva@users.noreply.github.com>2017-10-05 11:40:41 -0400
commit75984da4b22003d0e46a9fe1001978d999387636 (patch)
treef2c797dd5771ce468abd931d6bfe9d04c51ac2c0
parent4963f66653e29d913eba4811b1b88d931877193f (diff)
downloadcouchdb-75984da4b22003d0e46a9fe1001978d999387636.tar.gz
Handle deprecated random module
Use erlang release version to decide if the newer `rand` module is present or not. `erlang:function_exported(rand, uniform, 0)` could not be used here as it returns false when function isn't loaded, even if module and function are both available.
-rw-r--r--src/couch/rebar.config.script11
-rw-r--r--src/couch/src/couch_debug.erl2
-rw-r--r--src/couch/src/couch_multidb_changes.erl2
-rw-r--r--src/couch/src/couch_rand.erl57
-rw-r--r--src/couch/src/couch_util.erl3
-rw-r--r--src/couch/test/couch_btree_tests.erl8
-rw-r--r--src/couch/test/couch_file_tests.erl4
-rw-r--r--src/couch_log/test/couch_log_test.erl3
-rw-r--r--src/couch_replicator/src/couch_replicator_doc_processor.erl14
-rw-r--r--src/couch_replicator/src/couch_replicator_docs.erl2
-rw-r--r--src/couch_replicator/src/couch_replicator_scheduler_job.erl3
-rw-r--r--src/ddoc_cache/test/ddoc_cache_lru_test.erl2
12 files changed, 85 insertions, 26 deletions
diff --git a/src/couch/rebar.config.script b/src/couch/rebar.config.script
index 5586032d9..bd35e34bd 100644
--- a/src/couch/rebar.config.script
+++ b/src/couch/rebar.config.script
@@ -131,15 +131,18 @@ PortSpecs = case os:type() of
os:cmd("chmod +x priv/couchspawnkillable"),
BaseSpecs
end,
-
+PlatformDefines = [
+ {platform_define, "^R16", 'NORANDMODULE'},
+ {platform_define, "^17", 'NORANDMODULE'},
+ {platform_define, "win32", 'WINDOWS'}
+],
AddConfig = [
{port_specs, PortSpecs},
- {erl_opts, [
- {platform_define, "win32", 'WINDOWS'},
+ {erl_opts, PlatformDefines ++ [
{d, 'COUCHDB_VERSION', Version},
{i, "../"}
]},
- {eunit_compile_opts, [{platform_define, "win32", 'WINDOWS'}]}
+ {eunit_compile_opts, PlatformDefines}
].
lists:foldl(fun({K, V}, CfgAcc) ->
diff --git a/src/couch/src/couch_debug.erl b/src/couch/src/couch_debug.erl
index 858a4fb10..96c7a505f 100644
--- a/src/couch/src/couch_debug.erl
+++ b/src/couch/src/couch_debug.erl
@@ -508,7 +508,7 @@ random_processes(Acc, Depth) ->
end.
oneof(Options) ->
- lists:nth(random:uniform(length(Options)), Options).
+ lists:nth(couch_rand:uniform(length(Options)), Options).
tree() ->
diff --git a/src/couch/src/couch_multidb_changes.erl b/src/couch/src/couch_multidb_changes.erl
index 5efcccaac..b6a7873fb 100644
--- a/src/couch/src/couch_multidb_changes.erl
+++ b/src/couch/src/couch_multidb_changes.erl
@@ -302,7 +302,7 @@ notify_fold(DbName, {Server, DbSuffix, Count}) ->
% number of shards back to back during startup.
jitter(N) ->
Range = min(2 * N * ?AVG_DELAY_MSEC, ?MAX_DELAY_MSEC),
- random:uniform(Range).
+ couch_rand:uniform(Range).
scan_local_db(Server, DbSuffix) when is_pid(Server) ->
diff --git a/src/couch/src/couch_rand.erl b/src/couch/src/couch_rand.erl
new file mode 100644
index 000000000..f5a8fc6af
--- /dev/null
+++ b/src/couch/src/couch_rand.erl
@@ -0,0 +1,57 @@
+% 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(couch_rand).
+
+
+-export([
+ uniform/0,
+ uniform/1
+]).
+
+
+-ifdef(NORANDMODULE).
+
+
+uniform() ->
+ maybe_set_random_seed(),
+ random:uniform().
+
+
+uniform(N) ->
+ maybe_set_random_seed(),
+ random:uniform(N).
+
+
+maybe_set_random_seed() ->
+ case get(random_seed) of
+ undefined ->
+ {_, Sec, USec} = os:timestamp(),
+ Seed = {erlang:phash2(self()), Sec, USec},
+ random:seed(Seed);
+ _ ->
+ ok
+ end.
+
+
+-else.
+
+
+uniform() ->
+ rand:uniform().
+
+
+uniform(N) ->
+ rand:uniform(N).
+
+
+-endif.
diff --git a/src/couch/src/couch_util.erl b/src/couch/src/couch_util.erl
index 42d10ec1e..631f00b61 100644
--- a/src/couch/src/couch_util.erl
+++ b/src/couch/src/couch_util.erl
@@ -209,7 +209,8 @@ json_user_ctx(Db) ->
% returns a random integer
rand32() ->
- crypto:rand_uniform(0, 16#100000000).
+ <<I:32>> = crypto:strong_rand_bytes(4),
+ I.
% given a pathname "../foo/bar/" it gives back the fully qualified
% absolute pathname.
diff --git a/src/couch/test/couch_btree_tests.erl b/src/couch/test/couch_btree_tests.erl
index 35cf41604..3c8840a60 100644
--- a/src/couch/test/couch_btree_tests.erl
+++ b/src/couch/test/couch_btree_tests.erl
@@ -82,7 +82,7 @@ btree_open_test_() ->
sorted_kvs_test_() ->
Funs = kvs_test_funs(),
- Sorted = [{Seq, random:uniform()} || Seq <- lists:seq(1, ?ROWS)],
+ Sorted = [{Seq, couch_rand:uniform()} || Seq <- lists:seq(1, ?ROWS)],
{
"BTree with sorted keys",
{
@@ -97,7 +97,7 @@ sorted_kvs_test_() ->
}.
rsorted_kvs_test_() ->
- Sorted = [{Seq, random:uniform()} || Seq <- lists:seq(1, ?ROWS)],
+ Sorted = [{Seq, couch_rand:uniform()} || Seq <- lists:seq(1, ?ROWS)],
Funs = kvs_test_funs(),
Reversed = Sorted,
{
@@ -115,7 +115,7 @@ rsorted_kvs_test_() ->
shuffled_kvs_test_() ->
Funs = kvs_test_funs(),
- Sorted = [{Seq, random:uniform()} || Seq <- lists:seq(1, ?ROWS)],
+ Sorted = [{Seq, couch_rand:uniform()} || Seq <- lists:seq(1, ?ROWS)],
Shuffled = shuffle(Sorted),
{
"BTree with shuffled keys",
@@ -479,7 +479,7 @@ randomize(T, List) ->
end, randomize(List), lists:seq(1, (T - 1))).
randomize(List) ->
- D = lists:map(fun(A) -> {random:uniform(), A} end, List),
+ D = lists:map(fun(A) -> {couch_rand:uniform(), A} end, List),
{_, D1} = lists:unzip(lists:keysort(1, D)),
D1.
diff --git a/src/couch/test/couch_file_tests.erl b/src/couch/test/couch_file_tests.erl
index c16be16c4..a387615dd 100644
--- a/src/couch/test/couch_file_tests.erl
+++ b/src/couch/test/couch_file_tests.erl
@@ -311,14 +311,14 @@ check_header_recovery(CheckFun) ->
ok.
write_random_data(Fd) ->
- write_random_data(Fd, 100 + random:uniform(1000)).
+ write_random_data(Fd, 100 + couch_rand:uniform(1000)).
write_random_data(Fd, 0) ->
{ok, Bytes} = couch_file:bytes(Fd),
{ok, (1 + Bytes div ?BLOCK_SIZE) * ?BLOCK_SIZE};
write_random_data(Fd, N) ->
Choices = [foo, bar, <<"bizzingle">>, "bank", ["rough", stuff]],
- Term = lists:nth(random:uniform(4) + 1, Choices),
+ Term = lists:nth(couch_rand:uniform(4) + 1, Choices),
{ok, _, _} = couch_file:append_term(Fd, Term),
write_random_data(Fd, N - 1).
diff --git a/src/couch_log/test/couch_log_test.erl b/src/couch_log/test/couch_log_test.erl
index 17777304f..c7195f65f 100644
--- a/src/couch_log/test/couch_log_test.erl
+++ b/src/couch_log/test/couch_log_test.erl
@@ -80,6 +80,5 @@ check_levels(TestLevel, [CfgLevel | RestLevels]) ->
new_msg() ->
- random:seed(os:timestamp()),
- Bin = list_to_binary([random:uniform(255) || _ <- lists:seq(1, 16)]),
+ Bin = list_to_binary([couch_rand:uniform(255) || _ <- lists:seq(1, 16)]),
couch_util:to_hex(Bin).
diff --git a/src/couch_replicator/src/couch_replicator_doc_processor.erl b/src/couch_replicator/src/couch_replicator_doc_processor.erl
index 28eb17c16..d3c001f26 100644
--- a/src/couch_replicator/src/couch_replicator_doc_processor.erl
+++ b/src/couch_replicator/src/couch_replicator_doc_processor.erl
@@ -423,20 +423,20 @@ error_backoff(ErrCnt) ->
% ErrCnt is the exponent here. The reason 64 is used is to start at
% 64 (about a minute) max range. Then first backoff would be 30 sec
% on average. Then 1 minute and so on.
- random:uniform(?INITIAL_BACKOFF_EXPONENT bsl Exp).
+ couch_rand:uniform(?INITIAL_BACKOFF_EXPONENT bsl Exp).
-spec filter_backoff() -> seconds().
filter_backoff() ->
Total = ets:info(?MODULE, size),
- % This value scaled by the number of replications. If the are a lot of
- % them wait is longer, but not more than a day (?TS_DAY_SEC). If there
- % are just few, wait is shorter, starting at about 30 seconds. `2 *` is
- % used since the expected wait would then be 0.5 * Range so it is easier
- % to see the average wait. `1 +` is used because random:uniform only
+ % This value scaled by the number of replications. If the are a lot of them
+ % wait is longer, but not more than a day (?TS_DAY_SEC). If there are just
+ % few, wait is shorter, starting at about 30 seconds. `2 *` is used since
+ % the expected wait would then be 0.5 * Range so it is easier to see the
+ % average wait. `1 +` is used because couch_rand:uniform only
% accepts >= 1 values and crashes otherwise.
Range = 1 + min(2 * (Total / 10), ?TS_DAY_SEC),
- ?MIN_FILTER_DELAY_SEC + random:uniform(round(Range)).
+ ?MIN_FILTER_DELAY_SEC + couch_rand:uniform(round(Range)).
% Document removed from db -- clear ets table and remove all scheduled jobs
diff --git a/src/couch_replicator/src/couch_replicator_docs.erl b/src/couch_replicator/src/couch_replicator_docs.erl
index 9d844b9e7..d22b85f89 100644
--- a/src/couch_replicator/src/couch_replicator_docs.erl
+++ b/src/couch_replicator/src/couch_replicator_docs.erl
@@ -316,7 +316,7 @@ update_rep_doc(RepDbName, RepDocId, KVs, Wait) when is_binary(RepDocId) ->
throw:conflict ->
Msg = "Conflict when updating replication doc `~s`. Retrying.",
couch_log:error(Msg, [RepDocId]),
- ok = timer:sleep(random:uniform(erlang:min(128, Wait)) * 100),
+ ok = timer:sleep(couch_rand:uniform(erlang:min(128, Wait)) * 100),
update_rep_doc(RepDbName, RepDocId, KVs, Wait * 2)
end;
diff --git a/src/couch_replicator/src/couch_replicator_scheduler_job.erl b/src/couch_replicator/src/couch_replicator_scheduler_job.erl
index e7ce576f4..e2d8fb6d6 100644
--- a/src/couch_replicator/src/couch_replicator_scheduler_job.erl
+++ b/src/couch_replicator/src/couch_replicator_scheduler_job.erl
@@ -110,7 +110,6 @@ init(InitArgs) ->
do_init(#rep{options = Options, id = {BaseId, Ext}, user_ctx=UserCtx} = Rep) ->
process_flag(trap_exit, true),
- random:seed(os:timestamp()),
timer:sleep(startup_jitter()),
#rep_state{
@@ -468,7 +467,7 @@ format_status(_Opt, [_PDict, State]) ->
startup_jitter() ->
Jitter = config:get_integer("replicator", "startup_jitter",
?STARTUP_JITTER_DEFAULT),
- random:uniform(erlang:max(1, Jitter)).
+ couch_rand:uniform(erlang:max(1, Jitter)).
headers_strip_creds([], Acc) ->
diff --git a/src/ddoc_cache/test/ddoc_cache_lru_test.erl b/src/ddoc_cache/test/ddoc_cache_lru_test.erl
index 245511563..60605b9a5 100644
--- a/src/ddoc_cache/test/ddoc_cache_lru_test.erl
+++ b/src/ddoc_cache/test/ddoc_cache_lru_test.erl
@@ -28,7 +28,7 @@ recover(<<"pause", _/binary>>) ->
{ok, paused};
recover(<<"big", _/binary>>) ->
- {ok, [random:uniform() || _ <- lists:seq(1, 8192)]};
+ {ok, [couch_rand:uniform() || _ <- lists:seq(1, 8192)]};
recover(DbName) ->
{ok, DbName}.