pooled_gs.erl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. %% @doc A gen_server module that can be pooled by pooler. This module
  2. %% is used to test and demo pooler and plays the role of the pooled
  3. %% member.
  4. %%
  5. %% A pooled_gs is started with a `Type' which is intended to help
  6. %% identify the members for testing multi-pool scenarios. Each
  7. %% pooled_gs also sets a unique id. The type and id are retrieved
  8. %% using `get_id/1'.
  9. -module(pooled_gs).
  10. -behaviour(gen_server).
  11. -define(SERVER, ?MODULE).
  12. -include("pooler.hrl").
  13. %% ------------------------------------------------------------------
  14. %% API Function Exports
  15. %% ------------------------------------------------------------------
  16. -export([start_link/1,
  17. get_id/1,
  18. ping/1,
  19. ping_count/1,
  20. crash/1,
  21. error_on_call/1,
  22. do_work/2,
  23. stop/1
  24. ]).
  25. %% ------------------------------------------------------------------
  26. %% gen_server Function Exports
  27. %% ------------------------------------------------------------------
  28. -export([init/1, handle_call/3, handle_cast/2, handle_info/2,
  29. terminate/2, code_change/3]).
  30. %% ------------------------------------------------------------------
  31. %% API Function Definitions
  32. %% ------------------------------------------------------------------
  33. start_link(Args ={_Type}) ->
  34. % not registered
  35. gen_server:start_link(?MODULE, Args, []);
  36. start_link(Args ={_Type, _InitFun}) ->
  37. % not registered
  38. gen_server:start_link(?MODULE, Args, []).
  39. %% @doc return the type argument passed to this worker at start time
  40. %% along with this worker's unique id.
  41. get_id(S) ->
  42. gen_server:call(S, get_id).
  43. %% @doc In processing this request, the server will sleep for a time
  44. %% determined by a call to `random:uniform(T)'. Can be useful in
  45. %% stress-testing the pool to simulate consumers taking a member out
  46. %% of the pool for a varied request time.
  47. do_work(S, T) ->
  48. gen_server:call(S, {do_work, T}).
  49. ping(S) ->
  50. gen_server:call(S, ping).
  51. ping_count(S) ->
  52. gen_server:call(S, ping_count).
  53. crash(S) ->
  54. gen_server:cast(S, crash),
  55. sent_crash_request.
  56. error_on_call(S) ->
  57. gen_server:call(S, error_on_call).
  58. stop(S) ->
  59. gen_server:call(S, stop).
  60. %% ------------------------------------------------------------------
  61. %% gen_server Function Definitions
  62. %% ------------------------------------------------------------------
  63. -record(state, {
  64. type = "" :: string(),
  65. id :: reference(),
  66. ping_count = 0 :: non_neg_integer()
  67. }).
  68. init({Type}) ->
  69. {ok, #state{type = Type, id = make_ref()}};
  70. init({Type, StartFun}) ->
  71. StartFun(),
  72. {ok, #state{type = Type, id = make_ref()}}.
  73. handle_call(get_id, _From, State) ->
  74. {reply, {State#state.type, State#state.id}, State};
  75. handle_call({do_work, T}, _From, State) ->
  76. Sleep = ?RANDOM_UNIFORM(T),
  77. timer:sleep(Sleep),
  78. {reply, {ok, Sleep}, State};
  79. handle_call(ping, _From, #state{ping_count = C } = State) ->
  80. State1 = State#state{ping_count = C + 1},
  81. {reply, pong, State1};
  82. handle_call(ping_count, _From, #state{ping_count = C } = State) ->
  83. {reply, C, State};
  84. handle_call(error_on_call, _From, _State) ->
  85. erlang:error({pooled_gs, requested_error});
  86. handle_call(stop, _From, State) ->
  87. {stop, normal, stop_ok, State};
  88. handle_call(_Request, _From, State) ->
  89. {noreply, ok, State}.
  90. handle_cast(crash, _State) ->
  91. erlang:error({pooled_gs, requested_crash});
  92. handle_cast(_Msg, State) ->
  93. {noreply, State}.
  94. handle_info(_Info, State) ->
  95. {noreply, State}.
  96. terminate(_Reason, _State) ->
  97. ok.
  98. code_change(_OldVsn, State, _Extra) ->
  99. {ok, State}.