pooled_gs.erl 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  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([
  17. start_link/1,
  18. get_id/1,
  19. ping/1,
  20. ping_count/1,
  21. crash/1,
  22. error_on_call/1,
  23. do_work/2,
  24. stop/1
  25. ]).
  26. %% ------------------------------------------------------------------
  27. %% gen_server Function Exports
  28. %% ------------------------------------------------------------------
  29. -export([
  30. init/1,
  31. handle_call/3,
  32. handle_cast/2,
  33. handle_info/2,
  34. terminate/2,
  35. code_change/3
  36. ]).
  37. %% ------------------------------------------------------------------
  38. %% API Function Definitions
  39. %% ------------------------------------------------------------------
  40. start_link(Args = {_Type}) ->
  41. % not registered
  42. gen_server:start_link(?MODULE, Args, []);
  43. start_link(Args = {_Type, _InitFun}) ->
  44. % not registered
  45. gen_server:start_link(?MODULE, Args, []).
  46. %% @doc return the type argument passed to this worker at start time
  47. %% along with this worker's unique id.
  48. get_id(S) ->
  49. gen_server:call(S, get_id).
  50. %% @doc In processing this request, the server will sleep for a time
  51. %% determined by a call to `random:uniform(T)'. Can be useful in
  52. %% stress-testing the pool to simulate consumers taking a member out
  53. %% of the pool for a varied request time.
  54. do_work(S, T) ->
  55. gen_server:call(S, {do_work, T}).
  56. ping(S) ->
  57. gen_server:call(S, ping).
  58. ping_count(S) ->
  59. gen_server:call(S, ping_count).
  60. crash(S) ->
  61. gen_server:cast(S, crash),
  62. sent_crash_request.
  63. error_on_call(S) ->
  64. gen_server:call(S, error_on_call).
  65. stop(S) ->
  66. gen_server:call(S, stop).
  67. %% ------------------------------------------------------------------
  68. %% gen_server Function Definitions
  69. %% ------------------------------------------------------------------
  70. -record(state, {
  71. type = "" :: string(),
  72. id :: reference(),
  73. ping_count = 0 :: non_neg_integer()
  74. }).
  75. init({Type}) ->
  76. {ok, #state{type = Type, id = make_ref()}};
  77. init({Type, StartFun}) ->
  78. StartFun(),
  79. {ok, #state{type = Type, id = make_ref()}}.
  80. handle_call(get_id, _From, State) ->
  81. {reply, {State#state.type, State#state.id}, State};
  82. handle_call({do_work, T}, _From, State) ->
  83. Sleep = rand:uniform(T),
  84. timer:sleep(Sleep),
  85. {reply, {ok, Sleep}, State};
  86. handle_call(ping, _From, #state{ping_count = C} = State) ->
  87. State1 = State#state{ping_count = C + 1},
  88. {reply, pong, State1};
  89. handle_call(ping_count, _From, #state{ping_count = C} = State) ->
  90. {reply, C, State};
  91. handle_call(error_on_call, _From, _State) ->
  92. erlang:error({pooled_gs, requested_error});
  93. handle_call(stop, _From, State) ->
  94. {stop, normal, stop_ok, State};
  95. handle_call(_Request, _From, State) ->
  96. {noreply, ok, State}.
  97. handle_cast(crash, _State) ->
  98. erlang:error({pooled_gs, requested_crash});
  99. handle_cast(_Msg, State) ->
  100. {noreply, State}.
  101. handle_info(_Info, State) ->
  102. {noreply, State}.
  103. terminate(_Reason, _State) ->
  104. ok.
  105. code_change(_OldVsn, State, _Extra) ->
  106. {ok, State}.