anchor.diff:  %% ===================================================================
   %% gen_server callbacks
   
  +-spec init(_) -> {ok, state()}.
   init(_Args) ->
       process_flag(trap_exit, true),
       {ok, _} = fair_scheduler:start_link(),
  
positive.code:     end.
  
  -spec update_config_table([disco_config:host_info()], [host_name()],
                            [host_name()]) -> 'ok'.
  update_config_table(Config, Blacklist, GCBlacklist) ->
      gen_server:cast(?MODULE,
                      {update_config_table, Config, Blacklist, GCBlacklist}).
  
  -spec get_active(nonempty_string() | 'all') ->
      {'ok', [{nonempty_string(), task()}]}.
  get_active(JobName) ->
      gen_server:call(?MODULE, {get_active, JobName}).
  
  -spec get_nodeinfo('all') -> {'ok', [nodeinfo()]}.
  get_nodeinfo(Spec) ->
      gen_server:call(?MODULE, {get_nodeinfo, Spec}).
  
  -spec new_job(nonempty_string(), pid(), non_neg_integer()) -> 'ok'.
  new_job(JobName, JobCoord, Timeout) ->
      gen_server:call(?MODULE, {new_job, JobName, JobCoord}, Timeout).
  
  -spec kill_job(nonempty_string()) -> 'ok'.
  kill_job(JobName) ->
      gen_server:call(?MODULE, {kill_job, JobName}).
  -spec kill_job(nonempty_string(), non_neg_integer()) -> 'ok'.
  kill_job(JobName, Timeout) ->
      gen_server:call(?MODULE, {kill_job, JobName}, Timeout).
  
  -spec purge_job(nonempty_string()) -> 'ok'.
  purge_job(JobName) ->
      gen_server:cast(?MODULE, {purge_job, JobName}).
  
  -spec clean_job(nonempty_string()) -> 'ok'.
  clean_job(JobName) ->
      gen_server:call(?MODULE, {clean_job, JobName}).
  
  -spec new_task(task(), non_neg_integer()) -> 'ok' | 'failed'.
  new_task(Task, Timeout) ->
      gen_server:call(?MODULE, {new_task, Task}, Timeout).
  
  -spec connection_status(host_name(), 'up' | 'down') -> 'ok'.
  connection_status(Node, Status) ->
      gen_server:call(?MODULE, {connection_status, Node, Status}).
  
  -spec manual_blacklist(host_name(), boolean()) -> 'ok'.
  manual_blacklist(Node, True) ->
      gen_server:call(?MODULE, {manual_blacklist, Node, True}).
  
  -spec gc_blacklist([host_name()]) -> 'ok'.
  gc_blacklist(Hosts) ->
      gen_server:call(?MODULE, {gc_blacklist, Hosts}).
  
  % called from remote nodes
  -spec get_worker_jobpack(node(), nonempty_string()) ->
                                  {'ok', {file:io_device(), non_neg_integer(), pid()}}.
  get_worker_jobpack(Master, JobName) ->
      gen_server:call({?MODULE, Master}, {jobpack, JobName}).
  
  
negative.code:                 nodes :: gb_tree(),
                  purged :: gb_tree(),
                  jobpack_queue :: pid()}).
  -type state() :: #state{}.
  
  -define(PURGE_TIMEOUT, 86400000). % 24h
  
  