<commit_before>%% This Source Code Form is subject to the terms of
%% the Mozilla Public License, v. 2.0.
%% A copy of the MPL can be found in the LICENSE file or
%% you can obtain it at http://mozilla.org/MPL/2.0/.
%%
%% @author <NAME>
%% @copyright (c) 2012 <NAME> <<EMAIL>>
%% @doc
%%

-module(myxi_stats).

-behaviour(gen_server).

-include("include/myxi.hrl").

%% API
-export([start_link/2,
         connect/1,
         counter/2]).

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

-type message() :: {connect, pid(), erlang:timestamp()} |
                   {counter, atom(), pos_integer()}.

-record(s, {sock               :: gen_udp:socket(),
            host = "localhost" :: string(),
            port = 8126        :: inet:port_number(),
            ns = ""            :: string()}).

%%
%% API
%%

-spec start_link(string(), string()) -> ignore | {error, _} | {ok, pid()}.
%% @doc Start the stats process
start_link(Ns, Url) ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, {Ns, Url}, []).

%%
%% Stats
%%

-spec connect(pid()) -> ok.
%% @doc
connect(Conn) -> cast({connect, Conn, now()}).

-spec counter(atom(), pos_integer()) -> ok.
%% @doc
counter(Stat, Step) -> cast({counter, Stat, Step}).

%%
%% Callbacks
%%

-spec init({string(), string()}) -> {ok, #s{}}.
%% @hidden
init({Ns, Url}) ->
    lager:info("STATS-INIT"),
    process_flag(trap_exit, true),
    {Host, Port} = myxi_util:split_host(Url, 8125),
    {ok, Sock} = gen_udp:open(0, [binary]),
    {ok, #s{sock = Sock, host = Host, port = Port, ns = Ns}}.

-spec handle_call(_, _, #s{}) -> {reply, ok, #s{}}.
%% @hidden
handle_call(_Msg, _From, State) -> {reply, ok, State}.

-spec handle_cast(message(), #s{}) -> {noreply, #s{}}.
%% listener creates a myxi_connection
handle_cast({connect, Conn, Started}, State) ->
    gproc:reg(?PROP(Conn), Started),
    monitor(process, Conn),
    stat(State, counter, connect, 1),
    {noreply, State};
%% miscellaneous counter increment
handle_cast({counter, Stat, Step}, State) ->
    stat(State, counter, Stat, Step),
    {noreply, State}.

-spec handle_info(_, #s{}) -> {noreply, #s{}}.
%% @hidden myxi_connection terminates
handle_info({'DOWN', _Ref, process, Conn, Reason}, State) ->
    Started = gproc:get_value(?PROP(Conn)),
    gproc:unreg(?PROP(Conn)),
    Status = case Reason of
                 normal -> disconnect.soft;
                 _Other -> disconnect.hard
             end,
    stat(State, timer, duration, now_diff(now(), Started)),
    stat(State, counter, Status, 1),
    {noreply, State}.

-spec terminate(_, #s{}) -> ok.
%% @hidden
terminate(_Reason, #s{sock = Sock}) ->
    ok = gen_udp:close(Sock),
    ok.

-spec code_change(_, #s{}, _) -> {ok, #s{}}.<commit_msg>Fixing stats type specs<commit_after>%% This Source Code Form is subject to the terms of
%% the Mozilla Public License, v. 2.0.
%% A copy of the MPL can be found in the LICENSE file or
%% you can obtain it at http://mozilla.org/MPL/2.0/.
%%
%% @author <NAME>
%% @copyright (c) 2012 <NAME> <brend<EMAIL>>
%% @doc
%%

-module(myxi_stats).

-behaviour(gen_server).

-include("include/myxi.hrl").

%% API
-export([start_link/2,
         connect/1,
         counter/2]).

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

-type message() :: {connect, pid(), erlang:timestamp()} |
                   {counter, atom(), pos_integer()}.

-record(s, {sock               :: gen_udp:socket(),
            host = "localhost" :: string(),
            port = 8126        :: inet:port_number(),
            ns = ""            :: string()}).

%%
%% API
%%

-spec start_link(string(), string()) -> ignore | {error, _} | {ok, pid()}.
%% @doc Start the stats process
start_link(Ns, Url) ->
    gen_server:start_link({local, ?MODULE}, ?MODULE, {Ns, Url}, []).

%%
%% Stats
%%

-spec connect(pid()) -> ok.
%% @doc
connect(Conn) -> cast({connect, Conn, now()}).

-spec counter(atom(), pos_integer()) -> ok.
%% @doc
counter(Stat, Step) -> cast({counter, Stat, Step}).

%%
%% Callbacks
%%

-spec init({string(), string()}) -> {ok, #s{}}.
%% @hidden
init({Ns, Url}) ->
    lager:info("STATS-INIT"),
    process_flag(trap_exit, true),
    {Host, Port} = myxi_util:split_host(Url, 8125),
    {ok, Sock} = gen_udp:open(0, [binary]),
    {ok, #s{sock = Sock, host = Host, port = Port, ns = Ns}}.

-spec handle_call(_, _, #s{}) -> {reply, ok, #s{}}.
%% @hidden
handle_call(_Msg, _From, State) -> {reply, ok, State}.

-spec handle_cast(message(), #s{}) -> {noreply, #s{}}.
%% listener creates a myxi_connection
handle_cast({connect, Conn, Started}, State) ->
    gproc:reg(?PROP(Conn), Started),
    monitor(process, Conn),
    stat(State, counter, connect, 1),
    {noreply, State};
%% miscellaneous counter increment
handle_cast({counter, Stat, Step}, State) ->
    stat(State, counter, Stat, Step),
    {noreply, State}.

-spec handle_info({'DOWN', _, process, _, _}, #s{}) -> {noreply, #s{}}.
%% @hidden myxi_connection terminates
handle_info({'DOWN', _Ref, process, Conn, Reason}, State) ->
    Started = gproc:get_value(?PROP(Conn)),
    gproc:unreg(?PROP(Conn)),
    Status = case Reason of
                 normal -> disconnect.soft;
                 _Other -> disconnect.hard
             end,
    stat(State, timer, duration, now_diff(now(), Started)),
    stat(State, counter, Status, 1),
    {noreply, State}.

-spec terminate(_, #s{}) -> ok.
%% @hidden
terminate(_Reason, #s{sock = Sock}) ->
    ok = gen_udp:close(Sock),
    ok.

-spec code_change(_, #s{}, _) -> {ok, #s{}}.
{'fraction_non_alphanumeric': 0.2016214310891787, 'fraction_numerical': 0.00986958054282693, 'mean_word_length': 3.024822695035461, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 51, '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': '788043', 'n_tokens_mistral': 2044, 'n_tokens_neox': 1947, 'n_words': 497}