<commit_before>
-module(fair_scheduler_job).
-behaviour(gen_server).

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

-define(SCHEDULE_TIMEOUT, 30000).

-include("disco.hrl").

-type load() :: {non_neg_integer(), {binary(), node()}}.

start(JobName, JobCoord) ->
    case gen_server:start(fair_scheduler_job, {JobName, JobCoord},
            disco:debug_flags("fair_scheduler_job-" ++ JobName)) of
        {ok, Server} -> {ok, Server};
        Error ->
            % This happens mainly if the job coordinator has
            % already died.
            V = is_process_alive(JobCoord),
            if V ->
                % If it hasn't, this is a real error.
                Error;
            true ->
                % If it's dead, we can just remove a dummy
                % pid that will become zombie right away.
                % Scheduler monitoring will notice that it's
                % dead and react accordingly.
                {ok, spawn(fun() -> ok end)}
            end
    end.

-spec init({nonempty_string(), pid()}) -> _.
init({JobName, JobCoord}) ->
    process_flag(trap_exit, true),
    put(jobname, JobName),
    case catch link(JobCoord) of
        true ->
            {ok, {gb_trees:insert(nopref, {0, []},
                    gb_trees:empty()),
                  gb_trees:empty(), []}};
        R ->
            error_logger:info_report({"Linking failed", R}),
            {stop, normal}
    end.

% MAIN FUNCTION:
% Return a next task to be executed from this Job.
-spec next_task(jobinfo(), [jobinfo()], [node()]) ->
    {'ok', {node(), task()}} | 'none'.
next_task(Job, Jobs, AvailableNodes) ->
    schedule(schedule_local, Job, Jobs, AvailableNodes).

-spec schedule('schedule_local' | 'schedule_remote', jobinfo(), [jobinfo()], [node()]) ->
    {'ok', {node(), task()}} | 'none'.
schedule(Mode, Job, Jobs, AvailableNodes) -><commit_msg>Strengthen a spec to shut off a behaviour related discrepancy<commit_after>
-module(fair_scheduler_job).
-behaviour(gen_server).

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

-define(SCHEDULE_TIMEOUT, 30000).

-include("disco.hrl").

-type load() :: {non_neg_integer(), {binary(), node()}}.

start(JobName, JobCoord) ->
    case gen_server:start(fair_scheduler_job, {JobName, JobCoord},
            disco:debug_flags("fair_scheduler_job-" ++ JobName)) of
        {ok, Server} -> {ok, Server};
        Error ->
            % This happens mainly if the job coordinator has
            % already died.
            V = is_process_alive(JobCoord),
            if V ->
                % If it hasn't, this is a real error.
                Error;
            true ->
                % If it's dead, we can just remove a dummy
                % pid that will become zombie right away.
                % Scheduler monitoring will notice that it's
                % dead and react accordingly.
                {ok, spawn(fun() -> ok end)}
            end
    end.

-spec init({nonempty_string(), pid()}) ->
    {'ok', {gb_tree(), gb_tree(), []}} | {'stop', 'normal'}.
init({JobName, JobCoord}) ->
    process_flag(trap_exit, true),
    put(jobname, JobName),
    case catch link(JobCoord) of
        true ->
            {ok, {gb_trees:insert(nopref, {0, []},
                    gb_trees:empty()),
                  gb_trees:empty(), []}};
        R ->
            error_logger:info_report({"Linking failed", R}),
            {stop, normal}
    end.

% MAIN FUNCTION:
% Return a next task to be executed from this Job.
-spec next_task(jobinfo(), [jobinfo()], [node()]) ->
    {'ok', {node(), task()}} | 'none'.
next_task(Job, Jobs, AvailableNodes) ->
    schedule(schedule_local, Job, Jobs, AvailableNodes).

-spec schedule('schedule_local' | 'schedule_remote', jobinfo(), [jobinfo()], [node()]) ->
    {'ok', {node(), task()}} | 'none'.
schedule(Mode, Job, Jobs, AvailableNodes) ->
{'fraction_non_alphanumeric': 0.15479177119919718, 'fraction_numerical': 0.007024586051179127, 'mean_word_length': 2.3391959798994977, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 31, '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': '2866490', 'n_tokens_mistral': 1287, 'n_tokens_neox': 1221, 'n_words': 326}