<commit_before>%%%=============================================================================
%%% @copyright 2018, <NAME>
%%% @doc
%%%    Module that handle candidate block generation.
%%% @end
%%%=============================================================================
-module(aec_block_generator).

%% API
-export([start_link/0, stop/0]).

-export([get_candidate/0]).

-export([start_generation/0, stop_generation/0]).

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

-record(state,
        { generating = false    :: boolean()
        , worker = undefined    :: undefined | {pid(), term()}
        , candidate = undefined :: undefined | aec_blocks:block()
        , candidate_state = undefined :: undefined
                                       | aec_block_micro_candidate:block_info()
        , new_txs = []          :: list(aetx_sign:signed_tx())
        }).

%% -- API --------------------------------------------------------------------
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

stop() ->
    gen_server:stop(?MODULE).

-spec get_candidate() -> {ok, aec_blocks:block()} | {error, no_candidate}.
get_candidate() ->
    try
        gen_server:call(?MODULE, get_candidate, 100)
    catch _:_ ->
        {error, no_candidate}
    end.

start_generation() ->
    gen_server:cast(?MODULE, start_generation).

stop_generation() ->
    gen_server:cast(?MODULE, stop_generation).

%% -- gen_server callbacks ---------------------------------------------------

init([]) ->
    aec_events:subscribe(tx_created),
    aec_events:subscribe(tx_received),
    aec_events:subscribe(top_changed),
    {ok, #state{}}.

handle_call(get_candidate, _From, State = #state{ candidate = undefined }) ->
    {reply, {error, no_candidate}, State};
handle_call(get_candidate, _From, State = #state{ candidate = Candidate }) ->
    {reply, {ok, Candidate}, State};
handle_call(Req, _From, State) ->
    lager:info("Unexpected call: ~p", [Req]),
    {reply, ok, State}.

handle_cast(start_generation, State) ->
    lager:debug("start_generation"),
    {noreply, do_start_generation(State)};
handle_cast(stop_generation, State) ->
    lager:debug("stop_generation"),
    {noreply, do_stop_generation(State)};
handle_cast({new_candidate, Candidate, CandidateState}, State) ->
    epoch_mining:info("New candidate generated", []),
    lager:debug("New candidate generated", []),
    %% Only publish non-empty micro-blocks
    case aec_blocks:txs(Candidate) of
        [] -> ok;
        _  -> publish_candidate(Candidate)
    end,
    State1 = finish_worker(State),
    State2 = State1#state{ candidate = Candidate
                         , candidate_state = CandidateState },
    {noreply, maybe_start_worker_txs(State2)};
handle_cast({worker_done, Result}, State = #state{ worker = {Pid, _}}) ->
    State1 = finish_worker(State),
    lager:debug("Candidate worker ~p done ~p", [Pid, Result]),
    {noreply, State1};
handle_cast(Msg, State) ->
    lager:info("Unexpected message ~p", [Msg]),
    {noreply, State}.

handle_info({gproc_ps_event, Event, _Data}, State = #state{ generating = false }) ->
    lager:debug("ignored event ~p", [Event]),<commit_msg>Don't info log the production of empty microblocks<commit_after>%%%=============================================================================
%%% @copyright 2018, <NAME>
%%% @doc
%%%    Module that handle candidate block generation.
%%% @end
%%%=============================================================================
-module(aec_block_generator).

%% API
-export([start_link/0, stop/0]).

-export([get_candidate/0]).

-export([start_generation/0, stop_generation/0]).

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

-record(state,
        { generating = false    :: boolean()
        , worker = undefined    :: undefined | {pid(), term()}
        , candidate = undefined :: undefined | aec_blocks:block()
        , candidate_state = undefined :: undefined
                                       | aec_block_micro_candidate:block_info()
        , new_txs = []          :: list(aetx_sign:signed_tx())
        }).

%% -- API --------------------------------------------------------------------
start_link() ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, [], []).

stop() ->
    gen_server:stop(?MODULE).

-spec get_candidate() -> {ok, aec_blocks:block()} | {error, no_candidate}.
get_candidate() ->
    try
        gen_server:call(?MODULE, get_candidate, 100)
    catch _:_ ->
        {error, no_candidate}
    end.

start_generation() ->
    gen_server:cast(?MODULE, start_generation).

stop_generation() ->
    gen_server:cast(?MODULE, stop_generation).

%% -- gen_server callbacks ---------------------------------------------------

init([]) ->
    aec_events:subscribe(tx_created),
    aec_events:subscribe(tx_received),
    aec_events:subscribe(top_changed),
    {ok, #state{}}.

handle_call(get_candidate, _From, State = #state{ candidate = undefined }) ->
    {reply, {error, no_candidate}, State};
handle_call(get_candidate, _From, State = #state{ candidate = Candidate }) ->
    {reply, {ok, Candidate}, State};
handle_call(Req, _From, State) ->
    lager:info("Unexpected call: ~p", [Req]),
    {reply, ok, State}.

handle_cast(start_generation, State) ->
    lager:debug("start_generation"),
    {noreply, do_start_generation(State)};
handle_cast(stop_generation, State) ->
    lager:debug("stop_generation"),
    {noreply, do_stop_generation(State)};
handle_cast({new_candidate, Candidate, CandidateState}, State) ->
    %% Only publish non-empty micro-blocks
    case aec_blocks:txs(Candidate) of
        [] ->
            lager:debug("New empty microblock candidate generated, and discarded", []),
            ok;
        _  ->
            epoch_mining:info("New microblock candidate generated", []),
            publish_candidate(Candidate)
    end,
    State1 = finish_worker(State),
    State2 = State1#state{ candidate = Candidate
                         , candidate_state = CandidateState },
    {noreply, maybe_start_worker_txs(State2)};
handle_cast({worker_done, Result}, State = #state{ worker = {Pid, _}}) ->
    State1 = finish_worker(State),
    lager:debug("Candidate worker ~p done ~p", [Pid, Result]),
    {noreply, State1};
handle_cast(Msg, State) ->
    lager:info("Unexpected message ~p", [Msg]),
    {noreply, State}.

handle_info({gproc_ps_event, Event, _Data}, State = #state{ generating = false }) ->
    lager:debug("ignored event ~p", [Event]),
{'fraction_non_alphanumeric': 0.2270123605667772, 'fraction_numerical': 0.007235453723243895, 'mean_word_length': 3.196710942441493, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1353433', 'n_tokens_mistral': 2040, 'n_tokens_neox': 1959, 'n_words': 387}