pooled_gs.erl 3.4 KB

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