<commit_before>-module(mzb_director).

-export([start_link/5,
         pool_report/3,
         change_env/1,
         attach/0,
         stop_benchmark/1
         ]).

-behaviour(gen_server).
-export([init/1,
         handle_cast/2,
         handle_call/3,
         handle_info/2,
         terminate/2,
         code_change/3
        ]).

-include_lib("mzbench_language/include/mzbl_types.hrl").

-record(state, {
    super_pid  = undefined,
    failed     = 0,
    succeed    = 0,
    pools      = [],
    owner      = undefined,
    bench_name = undefined,
    stop_reason = undefined,
    script     = undefined,
    env        = undefined,
    nodes      = []
}).

%%%===================================================================
%%% API
%%%===================================================================

start_link(SuperPid, BenchName, Script, Nodes, Env) ->
    gen_server:start_link({global, ?MODULE}, ?MODULE, [SuperPid, BenchName, Script, Nodes, Env], []).

pool_report(PoolPid, Info, IsFinal) ->
    gen_server:cast({global, ?MODULE}, {pool_report, PoolPid, Info, IsFinal}).

change_env(Env) ->
    gen_server:call({global, ?MODULE}, {change_env, Env}, infinity).

attach() ->
    gen_server:call({global, ?MODULE}, attach, infinity).

stop_benchmark(Reason) ->
    gen_server:cast({global, ?MODULE}, {stop_benchmark, Reason}).

%%%===================================================================
%%% gen_server callbacks
%%%===================================================================

init([SuperPid, BenchName, Script, Nodes, Env]) ->
    lager:info("[ director ] Bench name ~p, director node ~p", [BenchName, erlang:node()]),
    {Pools, Env2} = mzbl_script:extract_pools_and_env(Script, Env),
    lager:info("[ director ] Pools: ~p, Env: ~p", [Pools, Env2]),
    _ = mzb_signaler:set_nodes(Nodes),
    gen_server:cast(self(), start_pools),
    {ok, #state{
        script = Pools,
        env = Env2,
        nodes = Nodes,
        bench_name = BenchName,
        super_pid = SuperPid
    }}.

handle_call({change_env, NewEnv}, _From, #state{script = Script, env = Env, nodes = Nodes} = State) ->
    lager:info("Changing env: ~p", [NewEnv]),
    MergedEnv = lists:foldl(
        fun ({K, V}, Acc) ->
            lists:keystore(K, 1, Acc, {K, V})
        end, Env, mzbl_script:normalize_env(NewEnv)),
    try
        {_, ModulesToLoad} = mzb_compiler:compile(Script, MergedEnv),
        ok = load_modules(ModulesToLoad, [node()|Nodes]),
        {reply, ok, State}
    catch
        _:E ->
            lager:error("Change env failed with reason ~p~nEnv:~p~nStacktrace:~p", [E, MergedEnv, erlang:get_stacktrace()]),
            {reply, {error, {internal_error, E}}, State}
    end;

handle_call(attach, From, State) ->
    maybe_report_and_stop(State#state{owner = From});<commit_msg>Save changed env in director state<commit_after>-module(mzb_director).

-export([start_link/5,
         pool_report/3,
         change_env/1,
         attach/0,
         stop_benchmark/1
         ]).

-behaviour(gen_server).
-export([init/1,
         handle_cast/2,
         handle_call/3,
         handle_info/2,
         terminate/2,
         code_change/3
        ]).

-include_lib("mzbench_language/include/mzbl_types.hrl").

-record(state, {
    super_pid  = undefined,
    failed     = 0,
    succeed    = 0,
    pools      = [],
    owner      = undefined,
    bench_name = undefined,
    stop_reason = undefined,
    script     = undefined,
    env        = undefined,
    nodes      = []
}).

%%%===================================================================
%%% API
%%%===================================================================

start_link(SuperPid, BenchName, Script, Nodes, Env) ->
    gen_server:start_link({global, ?MODULE}, ?MODULE, [SuperPid, BenchName, Script, Nodes, Env], []).

pool_report(PoolPid, Info, IsFinal) ->
    gen_server:cast({global, ?MODULE}, {pool_report, PoolPid, Info, IsFinal}).

change_env(Env) ->
    gen_server:call({global, ?MODULE}, {change_env, Env}, infinity).

attach() ->
    gen_server:call({global, ?MODULE}, attach, infinity).

stop_benchmark(Reason) ->
    gen_server:cast({global, ?MODULE}, {stop_benchmark, Reason}).

%%%===================================================================
%%% gen_server callbacks
%%%===================================================================

init([SuperPid, BenchName, Script, Nodes, Env]) ->
    lager:info("[ director ] Bench name ~p, director node ~p", [BenchName, erlang:node()]),
    {Pools, Env2} = mzbl_script:extract_pools_and_env(Script, Env),
    lager:info("[ director ] Pools: ~p, Env: ~p", [Pools, Env2]),
    _ = mzb_signaler:set_nodes(Nodes),
    gen_server:cast(self(), start_pools),
    {ok, #state{
        script = Pools,
        env = Env2,
        nodes = Nodes,
        bench_name = BenchName,
        super_pid = SuperPid
    }}.

handle_call({change_env, NewEnv}, _From, #state{script = Script, env = Env, nodes = Nodes} = State) ->
    lager:info("Changing env: ~p", [NewEnv]),
    MergedEnv = lists:foldl(
        fun ({K, V}, Acc) ->
            lists:keystore(K, 1, Acc, {K, V})
        end, Env, mzbl_script:normalize_env(NewEnv)),
    try
        {_, ModulesToLoad} = mzb_compiler:compile(Script, MergedEnv),
        ok = load_modules(ModulesToLoad, [node()|Nodes]),
        {reply, ok, State#state{env = MergedEnv}}
    catch
        _:E ->
            lager:error("Change env failed with reason ~p~nEnv:~p~nStacktrace:~p", [E, MergedEnv, erlang:get_stacktrace()]),
            {reply, {error, {internal_error, E}}, State}
    end;

handle_call(attach, From, State) ->
    maybe_report_and_stop(State#state{owner = From});
{'fraction_non_alphanumeric': 0.23732394366197182, 'fraction_numerical': 0.005985915492957746, 'mean_word_length': 3.330030487804878, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2542134', 'n_tokens_mistral': 1874, 'n_tokens_neox': 1826, 'n_words': 357}