PageRenderTime 44ms CodeModel.GetById 14ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/ce/src/ce_rec.erl

https://github.com/babo/jungerl
Erlang | 118 lines | 37 code | 14 blank | 67 comment | 0 complexity | bbfcd0b86778c7b866bb3739d29f62ad MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, AGPL-1.0
  1. %%% BEGIN ce_rec.erl %%%
  2. %%%
  3. %%% ce - Miscellaneous Programming Support Libraries for Erlang/OTP
  4. %%% Copyright (c)2003 Cat's Eye Technologies. All rights reserved.
  5. %%%
  6. %%% Redistribution and use in source and binary forms, with or without
  7. %%% modification, are permitted provided that the following conditions
  8. %%% are met:
  9. %%%
  10. %%% Redistributions of source code must retain the above copyright
  11. %%% notice, this list of conditions and the following disclaimer.
  12. %%%
  13. %%% Redistributions in binary form must reproduce the above copyright
  14. %%% notice, this list of conditions and the following disclaimer in
  15. %%% the documentation and/or other materials provided with the
  16. %%% distribution.
  17. %%%
  18. %%% Neither the name of Cat's Eye Technologies nor the names of its
  19. %%% contributors may be used to endorse or promote products derived
  20. %%% from this software without specific prior written permission.
  21. %%%
  22. %%% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
  23. %%% CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
  24. %%% INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
  25. %%% MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  26. %%% DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  27. %%% LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
  28. %%% OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  29. %%% PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  30. %%% OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  31. %%% ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  32. %%% OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  33. %%% OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  34. %%% POSSIBILITY OF SUCH DAMAGE.
  35. %% @doc Remote Execution Contexts (<code>rec</code>).
  36. %%
  37. %% <p>'Remote Execution Context' is basically a
  38. %% fancy way of saying 'workaround for <code>rpc</code>'.</p>
  39. %%
  40. %% <p>Some operations, such as <code>file:open/2</code>, return an
  41. %% object which is owned by the process that created it. When the
  42. %% parent process dies, that object is expunged.</p>
  43. %%
  44. %% <p><code>rpc:call/4</code> is not useful for such an operation,
  45. %% because it executes the given function with a short-lived process.</p>
  46. %%
  47. %% <p>A viable workaround is to instead use <code>ce_rec:start/1</code>
  48. %% to create a long-lived process ('execution context') on a remote node,
  49. %% <code>ce_rec:rpc/2</code> to execute such an operation in that context,
  50. %% and finally <code>ce_rec:stop/1</code> when the objects owned by the
  51. %% remote execution context are no longer needed.</p>
  52. %%
  53. %% @end
  54. -module(ce_rec).
  55. -vsn('JUNGERL').
  56. -author('catseye@catseye.mb.ca').
  57. -copyright('Copyright (c)2003 Cat`s Eye Technologies. All rights reserved.').
  58. -export([start/1, stop/1]).
  59. -export([rpc/2, rpc/3]).
  60. %% @spec start(node()) -> rec()
  61. %% rec() = pid()
  62. %% @doc Starts an execution context on the given node.
  63. start(Node) ->
  64. spawn_link(Node, fun() -> execution_context() end).
  65. %% @spec stop(rec()) -> ok | {error, Reason}
  66. %% @doc Shuts down the given execution context.
  67. stop(Pid) ->
  68. Pid ! {self(), stop},
  69. receive
  70. {Pid, stopped} ->
  71. ok
  72. after 10000 ->
  73. {error, timeout}
  74. end.
  75. %% @spec rpc(pid(), fun()) -> term()
  76. %% @equiv rpc(Pid, Fun, 10000)
  77. rpc(Pid, Fun) ->
  78. rpc(Pid, Fun, 10000).
  79. %% @spec rpc(pid(), fun(), Timeout::integer()) -> term()
  80. %% @doc Executes a <code>fun/0</code> in a given remote execution context.
  81. %% Returns the result of the fun. May exit with <code>timeout</code> if
  82. %% the call lasts more than <code>Timeout</code> milliseconds.
  83. rpc(Pid, Fun, Timeout) ->
  84. Pid ! {self(), do, Fun},
  85. receive
  86. {Pid, done, Result} ->
  87. Result
  88. after Timeout ->
  89. exit(timeout)
  90. end.
  91. %% @spec execution_context() -> never_returns()
  92. %% @doc Driver loop for each remote execution context.
  93. execution_context() ->
  94. receive
  95. {Pid, do, Fun} ->
  96. Pid ! {self(), done, Fun()},
  97. execution_context();
  98. {Pid, stop} ->
  99. Pid ! {self(), stopped},
  100. ok;
  101. _ ->
  102. execution_context()
  103. end.
  104. %%% END of ce_rec.erl %%%