2016-12-03 8 views
1

Я пытаюсь обновить приложение riak_core erlang во время его работы.Обновление приложения riak_core с помощью relup

Простые обновления работают. Я использую rebar3 и relflow для успешного обновления приложения. Однако, если я изменяю внутренности vnode и использую relflow и rebar3 relup для создания новой версии, vnode перестает работать. Внод называется «кавер».

После горячего обновления, он выходит из строя на данный момент:

DocIdx = riak_core_util:chash_key({<<"run">>, term_to_binary(os:timestamp())}), 

, что приводит к ошибке:

** exception error: bad argument 
    in function lists:keyfind/3 
     called as lists:keyfind(chash_keyfun,1,[{name,<<"run">>}|undefined]) 
    in call from riak_core_util:chash_key/2 (_build/default/lib/riak_core/src/riak_core_util.erl, line 266) 
    in call from cavv_vnode:run/0 (_build/prod/lib/cavv/src/cavv_vnode.erl, line 38) 

Мой relup выглядит следующим образом:

{"0.1.2", 
[{"0.1.1",[], 
    [{load_object_code,{cavv,"20161203-211601-relflow",[cavv_vnode]}}, 
    point_of_no_return, 
    {load,{cavv_vnode,brutal_purge,brutal_purge}}]}], 
[{"0.1.1",[],[point_of_no_return]}]}. 

Am I что-то не хватает? Должен ли я перезапустить некоторый мастер-vnode? Я попытался перезапустить некоторых супервизоров, но безуспешно.

Глядя на исходный код riak_core:

%% @spec chash_key(BKey :: riak_object:bkey()) -> chash:index() 
%% @doc Create a binary used for determining replica placement. 
chash_key({Bucket,_Key}=BKey) -> 
    BucketProps = riak_core_bucket:get_bucket(Bucket), 
    chash_key(BKey, BucketProps). 

%% @spec chash_key(BKey :: riak_object:bkey(), [{atom(), any()}]) -> 
%%   chash:index() 
%% @doc Create a binary used for determining replica placement. 
chash_key({Bucket,Key}, BucketProps) -> 
    {_, {M, F}} = lists:keyfind(chash_keyfun, 1, BucketProps), %% <-- Line 266 
    M:F({Bucket,Key}). 

Я пытался понять, что происходит, но с трудом понимания того, что происходит. Почему-то что-то в BucketProps не определено, что не должно быть неопределенным после обновления?

Когда я перезапускаю все приложение, оно работает как шарм.

Я что-то пропустил во время моего горячего обновления с помощью riak_core? Или лучше просто закрыть весь узел, затем обновить и запустить его снова и забыть о обновлении горячего кода?

UPDATE В то же время я обнаружил, что что-то пойдет не так с riak_core_bucket.

Запуск следующее: riak_core_bucket:get_bucket(<<"run">>).

Перед обновлением:

[{name,<<"run">>}, 
{allow_mult,false}, 
{basic_quorum,false}, 
{big_vclock,50}, 
{chash_keyfun,{riak_core_util,chash_std_keyfun}}, 
{dvv_enabled,false}, 
{dw,quorum}, 
{last_write_wins,false}, 
{linkfun,{modfun,riak_kv_wm_link_walker,mapreduce_linkfun}}, 
{n_val,3}, 
{notfound_ok,true}, 
{old_vclock,86400}, 
{postcommit,[]}, 
{pr,0}, 
{precommit,[]}, 
{pw,0}, 
{r,quorum}, 
{rw,quorum}, 
{small_vclock,50}, 
{w,quorum}, 
{young_vclock,20}] 

После обновления:

[{name,<<"run">>}|undefined] 

Неопределенное возвращается app_helper:get_env(riak_core, default_bucket_props). после обновления.

я обнаружил, что пытается обработать sys.config во время обновления:

Warning: "_build/prod/rel/cavv/releases/0.1.2/sys.config" missing (optional) 

Используя сгенерированный app.conf не достаточно, так как он не содержит все значения конфигурации, которые ранее показали. Используя его только выходы: [{n_val,3}].

Возможно, что-то с каракатицей не перегружает файлы конфигов?

UPDATE2

Совершено еще немного покопаться. После обновления application:get_all_env(riak_core). возвращает разные значения. Есть идеи?

ответ

1

я узнал, что после обновления, все значения среды удаляются:

http://erlang.org/doc/design_principles/release_handling.html#id84983

Specifically, the application configuration parameters are automatically updated according to (in increasing priority order):

The data in the boot script, fetched from the new application resource file App.app The new sys.config Command-line arguments -App Par Val This means that parameter values set in the other system configuration files and values set using application:set_env/3 are disregarded.

Для сброса значений, установленных riak_core, я использую простую функцию:

set_defaults() -> 
    riak_core_bucket:append_bucket_defaults(riak_core_bucket_type:defaults(default_type)). 

Я вызываю это в своем файле с повторением:

{apply,{cavv_app,set_defaults,[]}}, 

Значения по умолчанию устанавливаются обычно во время запуска приложения riak_core здесь:

https://github.com/basho/riak_core/blob/develop/src/riak_core_app.erl#L42

Но эта функция не экспортируется и не подвергается.

Не знаю, было ли это наиболее элегантное решение, с которым я столкнулся. Любые идеи приветствуются.